簡介
這篇文章是我在學習ASP.NET MVC程序傳值方式梳理總結的筆記。在ASP.NET MVC中,頁面間和Controller與View之間主要有以下幾種小量數據傳值方式, ViewData、ViewBag、TempData、Session變量。 我們是幸運的,微軟提供給了我們這么多傳值方法,但選擇越多越讓人抓狂,這些技術每一種都有自己的優點和缺點,我應該何時使用哪一種傳值方式呢?
正文
上面的這四種方法中,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, 理解難免有偏差, 如有錯誤, 還望指正。
參考資料:
- http://www.coderewind.com/article/how-to-get-started-with-asp-net-mvc
- http://www.dotnet-tricks.com/Tutorial/mvc/9KHW190712-ViewData-vs-ViewBag-vs-TempData-vs-Session.html
- http://www.codeproject.com/Articles/259560/Learn-MVC-Model-view-controller-Step-by-Step-in-7
- http://blog.csdn.net/shuaishenkkk/article/details/8570463
- A Beginner's Tutorial on Various Ways of Passing Data in ASP.NET MVC Application
- Using TempData while <sessionState mode="Off" />
