ViewData、ViewBag、TempData、Session的區別與聯系


簡介

這篇文章是我在學習ASP.NET MVC程序傳值方式梳理總結的筆記。在ASP.NET MVC中,頁面間和Controller與View之間主要有以下幾種小量數據傳值方式, ViewDataViewBagTempDataSession變量。 我們是幸運的,微軟提供給了我們這么多傳值方法,但選擇越多越讓人抓狂,這些技術每一種都有自己的優點和缺點,我應該何時使用哪一種傳值方式呢?

正文

上面的這四種方法中,ViewData和ViewBag其實是一回事, ViewBag其實是對ViewData的封裝, 其內部其實是使用ViewData實現數據存儲的。唯一的不同點是,ViewBag可以存儲動態類型(dynamic)的變量值, 而ViewData只能存儲String Key/Object Value字典數組。 所以我們可以將這四種方法歸為三大類, ViewData和ViewBag, TempData, Session。

ViewData["Message"] = "Hello ASP.NET MVC";
// Or
ViewBag.Message = "Hello ASP.NET MVC";

TempData也是一個String Key/Object Value字典數組。 和ViewData與ViewBag不同的是其所存儲的數據對象的生命周期。 如果頁面發生了跳轉(Redirection),ViewBag和ViewData中的值將不復存在, 但是TempData中的值依然還在。 換句話講, ViewBag和ViewData存儲的值的生命周期只有在從Controller到View中, 而TempData中的數據不僅在從Controller到View中有效,在不同的Action之間或者從一個頁面跳轉到另一頁面(Controller to Controller)后依然有效。

TempData["Message"] = "Hello ASP.NET MVC";

Session其實和ViewData類似,也是一個String Key/Object Value字典數組。但是,Session是存儲在客戶端的Cookies中,所以它的生命周期是最長的。 但是,正因為其存儲的客戶端, 所以必須確保沒有敏感機密的信息存儲其中

Session["Message"] = "Hello ASP.NET MVC";

下面我們對每一個傳值方法的特點進行以下總結。

ViewData

  • ViewData是一個繼承自ViewDataDictionary類的Dictionary對象。
  • ViewData用來從Controller向對應的View傳遞值。
  • ViewData的只在當前當前的請求中有效,生命周期和View相同,其值不能在多個請求中共享。
  • 在重定向(redirection)后,ViewData中存儲的變量值將變為null。
  • 在取出ViewData中的變量值是,必須進行合適的類型轉換(隱式或顯式)和空值檢查。

下面我們來看一個簡單的例子,演示一下如何使用ViewData來從Controller向View傳值。

public ActionResult Index()
{
    ViewData["Message"] = "This is a message from ViewData";

    return View();
}

然后,我們從視圖中取出這個變量,

執行后,你將會在瀏覽器中看到如下的結果,

可能你注意到了,我在從ViewData中取出變量Message時並沒有對其進行類型轉換,那時因為我們存儲的是一個簡單類型的變量值。假如存儲的是復雜對象,在取出是必須進行類型轉換。

綜上, ViewData更適合從Controller向View傳遞簡單對象數據時使用。

ViewBag

  • ViewBag是一個動態類型變量(dynamic),這是C# 4.0引入的新特性,變量類型會在運行時進行解析。
  • ViewBag基本上是ViewData的包裝,也是用來從Controller向View來傳遞值的。
  • ViewBag也只在當前的請求中有效。
  • 在重定向(redirection)后,ViewBag中存儲的變量值將變為null
  • 因為ViewBag是動態類型,所以我們在取得其值時,不需要進行類型轉換。

同樣,我們通過一個簡單的例子來演示一下如何利用ViewBag從Controller向View傳遞數據。

public ActionResult Index()
{
    ViewBag.Message = "This is a message from ViewBag";

    return View();
}

然后,在視圖中取出數據並顯示,

最后,執行程序,你將會在瀏覽器中看到如下結果,

綜上, ViewBag更適合從Controller向View傳遞復雜對象數據時使用, 因為取出存儲在其中的數據變量時無需進行類型轉換。

TempData

  • TempData是一個繼承自TempDataDictionary類的字典對象,它默認情況下是基於Session存儲機制之上的。(備注: 你也可以讓你的TempData基於其他存儲機制之上, 我們可以提供我們自定義的ITempDataProvider來完成,具體可以參見: Session-less Controllers and TempData in ASP.NET MVC)
  • TempData是用來在多個Actions或從當前請求向子請求, 頁面發生了重定向(Redirection)時傳遞共享數據。
  • 只有在目標視圖(View)完全加載后才有效。
  • 在取出TempData存儲的變量值時,必須進行合適的類型轉換(隱式或顯式)和空值檢查。

下面,我們透過一個例子來演示一下如何在兩個Action方法中傳遞數據。

首先,創建一個客戶Model類,如下:

public class Customer
{
    public int Id { get; set; }
    public string Code { get; set; }
    public double Amount { get; set; }
}

然后,在Controller中加入如下代碼:

public ActionResult DisplayCustomer1()
{
    Customer customer = new Customer
    {
        Id = 1001,
        Code = "100101",
        Amount = 100
    };

    TempData["OneCustomer"] = customer;

    return RedirectToAction("DisplayCustomer2");
}

public ActionResult DisplayCustomer2()
{
    Customer customer = TempData["OneCustomer"] as Customer;

    return View(customer);
}

最后,創建一個強類型視圖(Strong Typed View)來顯示客戶信息。

執行程序,瀏覽器中會顯示如下結果:

綜上, TempData主要用在需要在多個Actions或者頁面重定向時共享傳遞數據時使用。

Session

  • Session也是ASP.NET MVC程序傳遞值的一種方式,但與TempData不同,用戶的整個會話中Session都不會過期。
  • Session在同一用戶會話過程中的所有請求中有效,比如,刷新頁面。
  • Session中的值也需要進行類型轉換(隱式或顯式)和非空檢查。

我們仍然使用上面的這個例子,假如我們不用TempData而是使用Session, 也可以得到同樣的結果。

public ActionResult DisplayCustomer1()
{
    Customer customer = new Customer
    {
        Id = 1001,
        Code = "100101",
        Amount = 100
    };

    Session["OneCustomer"] = customer;

    return RedirectToAction("DisplayCustomer2");
}

public ActionResult DisplayCustomer2()
{
    Customer customer = Session["OneCustomer"] as Customer;

    return View(customer);
}

Session的生命周期是最長的,但是它默認使用的是Cookies來存儲數據,所以使用的時候必須注意數據保密的問題。

綜上, Session主要用在需要在多個Controllers, Actions and Views共享數據(非敏感數據)時使用。

圖說傳遞方式的生命周期

Maintains data between ViewData/ViewBag TempData ( For single request) Session
Controller to Controller No Yes Yes
Controller to View Yes Yes Yes
View to Controller No No Yes

后記

本文試圖通過介紹ASP.NET MVC程序中傳遞小量數據的幾種機制的優缺點和適用場景。 本文只是一篇學習筆記,筆者初學ASP.NET MVC, 理解難免有偏差, 如有錯誤, 還望指正。

參考資料:

ASP.NET MVC學習筆記系列


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM