The diffrence between TempData and ViewBag and ViewData
这个问题让我想起上个去面试的时候,他们公司的技术总监问的我的那个问题,跟这个类似,只是当时不是很清楚,今天碰到了,好好总结一下。
先看老外写的文章:
《pro ASP.NET MVC3》中:
This is a key/value dictionary, similar to the session data and View Bag features we have used previously.
The key difference is that TempData is deleted at the end of the HTTP request
We can’t use ViewBag in this situation because the user is being redirected. ViewBag passes data
between the controller and view, and it can’t hold data for longer than the current HTTP request. We
could have used the session data feature, but then the message would be persistent until we explicitly
removed it, which we would rather not have to do. So, the Temp Data feature is the perfect fit. The data
is restricted to a single user’s session (so that users don’t see each other’s TempData) and will persist until
we have read it. We will read the data in the view rendered by the action method to which we have
redirected the user.
首先,这说明,TempData的值会在HTTP请求结束的时候被删除。
Stackflow上老外的解释:
................
2)ViewBag, ViewData
Allows you to store data in a controller action that will be used in the corresponding view. This assumes that the action returns a view and doesn't redirect. Lives only during the current request.
...................
这说明,ViewBag 和ViewData 都只能在当前的Request中有效。
再看中国人自己的总结:
(来源:http://hi.baidu.com/%B4%F3%CE%B0/blog/item/a56c2a38a5372f3db8998fe2.html)
ViewData 和 TempData 都可以传递弱类型数据,区别如下:
ViewData 只在当前 Action 中有效,生命周期和 View 相同;
TempData 的数据至多只能经过一次Controller传递,并且每个元素至多只能被访问一次,访问以后,自动被删除。
TempData 一般用于临时的缓存内容或抛出错误页面时传递错误信息,可以将TempData 在使用之前存储到相应的 ViewData 中以备循环使用。
Index
public ActionResult Index()
{
ViewBag.Message = "Welcome to ASP.NET MVC!";
ViewData["myName"] = "我的名字";
TempData["myAgeOne"] = "26岁";
TempData["myAgeTwo"] = "27岁";
return View();
}
姓名:@ViewData["myName"]
<br />
年龄1:@TempData["myAgeOne"]
About
姓名:@ViewData["myName"]
<br />
年龄1:@TempData["myAgeOne"]
<br />
年龄2:@TempData["myAgeTwo"]
ViewBag.Name=ViewData["Name"];
相同:使用同一个字典集合(数据源)
不同:ViewBag 是 MVC3 新增语法,ViewBag 不再是字典的键值对结构,而是 dynamic 动态类型,它会在程序运行的时候动态解析。
Dynamically Typed Object 动态类型
C#4.0加入了dynamic关键字,可以申明一个变量的static类型为dynamic。
使用dynamic的好处在于,可以不去关心对象是来源于COM, IronPython, HTML DOM或者反射,只要知道有什么方法可以调用就可以了,剩下的工作可以留给runtime
以上的文章解释了ViewBag 和 ViewData 的区别。
实践出真知:
自己写程序验证这三者的区别:
1.Controller里
public ViewResult Test()
{
TempData["a"] = "TempData数据";
ViewBag[“a”] = "ViewBag数据";
ViewData["a"] = "ViewData数据";
return View();
}
编译时程序报错,证实ViewBag确是动态类型,改成ViewBag.Data 编译通过。
2.Controller跳转
新添加一个方法:
public ViewResult Test2()
{
return View();
}
该Action是有Controller一跳转过来的,运行之后如图:
说明三者的值都为空。
3.修改Test的内容如下:
public ActionResult Test()
{
TempData["a"] = "TempData数据";
ViewBag.Data = "ViewBag数据";
ViewData["a"] = "ViewData数据";
return RedirectToAction("Test2");
}
结果:
这说明,ViewBag和ViewData确实是只在当前Action内有效,而TempData则可以在不同Action之间有效。
4.将代码改成如下:
public ActionResult Test()
{
TempData["a"] = "TempData数据";
ViewBag.Data = "ViewBag数据";
ViewData["a"] = "ViewData数据";
return RedirectToAction("Test2");
}
public ViewResult Test2()
{
var model = new Data { A = TempData["a"].ToString() };
//B = ViewBag.Data,
//C = ViewData["a"].ToString() };
return View(model);
}
只有TempData能够跨Action传值,而ViewBag和ViewData则不能传值。
至此,可以看出,三者最大的区别就是ViewBag是动态类型,其值由编译器完成确定且是MVC3新加的类型,ViewData 和 ViewBag都只能在当前Action作用范围内有效,而TempData是用于临时存储,会在Request结束时自动删除,可以跨Action传值。