文章内容
2017/5/18 12:09:56,作 者: 黄兵
asp.net mvc ViewData,ViewBag和TempData
我经常看到入门级开发人员在ASP.NET MVC中与ViewData,ViewBag和TempData之间的差异和使用情况。虽然有很多关于这个话题的文章和博客文章,我会尽量解释一下。
首先,ViewData,ViewBag和TempData都是ASP.NET MVC中的三个对象,用于在不同的场景中传送或传递数据。在以下情况下,您可能需要传递数据:
· 从控制器传递数据来查看;
· 将数据从一个控制器传递到另一个控制器;
· 将数据从一个动作传递给另一个动作;
· 在后续的HTTP请求之间传递数据
在较高级别,我们可以描述使用ViewData,ViewBag和TempData,如下图所示:

从控制器传递数据到视图
让我们考虑一下您从控制器传递数据以查看的场景。通常,我们使用模型将复杂数据传递给视图。这里假设我们有一个强类型的View,它正在使用如下列表所示的数据模型列表:
public ActionResult Index(){ List<Product> p = new List<Product>() {
new Product { Id = 1, Name = "Pen", Price = 300 }, new Product { Id = 2, Name = "Pencil", Price = 100 } };
return View(p);}在视图中,通过渲染模型显示数据,如下列所示:
<table class="table"> <tr> <th> @Html.DisplayNameFor(model => model.Name) </th> <th> @Html.DisplayNameFor(model => model.Price) </th> <th></th> </tr> @foreach (var item in Model) { <tr> <td> @Html.DisplayFor(modelItem => item.Name) </td> <td> @Html.DisplayFor(modelItem => item.Price) </td> <td> @Html.ActionLink("Edit", "Edit", new { id=item.Id }) | @Html.ActionLink("Details", "Details", new { id=item.Id }) | @Html.ActionLink("Delete", "Delete", new { id=item.Id }) </td> </tr> }</table>现在我们需要将数据(除型号)传递给控制器的视图。数据可以通过两种方式传递。

让我们假设除了产品数据模型之外,我们还想将一个简单的字符串传递给视图。
使用ViewBag传递数据
我们可以使用ViewBag传递数据,如下列所示:
public ActionResult Index(){ ViewBag.data1 = "I am ViewBag data"; return View(p);}在视图中,ViewBag数据可以作为ViewBag的属性读取,如下列所示:
<h2>@ViewBag.data1</h2>使用ViewData传递数据
我们可以使用ViewData传递数据,如下列所示:
public ActionResult Index(){ ViewData["data1"] = "I am ViewBag data"; return View(p);}在视图中,ViewData数据可以作为ViewData的字符串值对读取,如下列所示:
<h2>@ViewData["data1"]</h2>我们来看看ViewData和ViewBag之间的区别。ViewBag是基于动态类型的动态属性,而ViewData是一个字典对象。我们可以从ViewBag中读取数据作为属性,并从ViewData中读取数据作为键值对。关于两者的一些要点如下:
ViewData的
· 它是ViewDataDictionary类的一个属性。
· 数据可以以键值对的形式传递。
· 要查看视图中的复杂类型数据,需要进行类型转换。
· 为了避免异常,需要进行空检查。
· ViewData的生命只限于当前请求,并且在重定向时变为空。
· ViewData是ControllerBase类的一个属性
ViewBag
· 它是动态类型的属性。
· 数据作为对象的属性传递。
· 不需要类型转换来读取数据。
· 不需要空检。
· ViewBag的生命限制在当前请求中,并且在重定向时变为空。
· ViewBag是ControllerBase类的属性。
在ControllerBase类中,两者都定义为如下图所示的属性:

我们可以将ViewBag和ViewData汇总为对象,用于将数据从控制器传递到单个周期中。在ViewBag和ViewData中分配的值在下一个HTPP请求中被取消,或导航到其他视图。
TempData的
ViewData和ViewBag的主要属性之一就是它们的生命周期只限于一个HTTP请求。在重定向时,它们丢失数据。我们可能有其他情况,将数据从一个HTTP请求传递到下一个HTTP请求; 例如,将数据从一个控制器传递到另一个控制器,或将一个操作传递给其他操作。TempData用于将数据从一个请求传递到下一个请求。

让我们说,我们要导航到索引操作中的读取操作,并且在导航时,将数据从索引操作传递到读取操作。 所以在Index操作中,我们可以将值分配给TempData,如下列所示:
public ActionResult Index(){ TempData["data1"] = "I am from different action"; return RedirectToAction("Read"); }我们可以读取TempData作为键值对。在读取操作中,TempData可以如下列所示读取:
public string Read(){string str;str = TempData["data1"].ToString();return str;}
像ViewData一样,TempData也是一个字典对象,要读取数据,需要进行类型转换和空值检查。请记住,TempData可以将数据仅保留到后续的HTTP请求。当您非常确定重定向时,请使用TempData传递数据。
关于TempData的一些观点如下:
· TempData用于将数据从一个HTTP请求传递到下一个HTTP请求。
o 换句话说,TempData用于将数据从一个控制器传递到另一个控制器或操作到另一个操作。
· TempData是BaseController类的属性。
· TempData将数据存储在会话对象中
· TempData是ControllerBase类的属性
· 要读取数据,需要进行 打字和空检。
· TempData的类型是TempDataDictionary。
· TempData适用于HTTP重定向,如HTTP 302/303状态码
概要
ViewData,ViewBag和TempData用于在控制器,动作和视图之间传递数据。要从控制器传递数据以查看,可以使用ViewData或ViewBag。要将数据从一个控制器传递到另一个控制器,可以使用TempData。
我希望现在ViewBag,ViewData和TempData的概念更清楚一些 - 感谢阅读!
本文翻译自:What are ViewData, ViewBag, and TempData in ASP.NET MVC?
评论列表