ViewData 和 ViewBag都是页面级别的生命周期,TempData--Passing data between the current and next HTTP requests

TempData默认是实现方式--存在session中,所以结论很简单,能不用就不用。。要么负载时就麻烦了。

Passing data between the current and next HTTP requests - See more at: http://www.rachelappel.com/when-to-use-viewbag-viewdata-or-tempdata-in-asp.net-mvc-3-applications#sthash.rVx9t9N8.dpuf

先上源码:

ControllerBase中如下定义2个:

private DynamicViewDataDictionary _dynamicViewDataDictionary;
private TempDataDictionary _tempDataDictionary; public dynamic ViewBag {
get {
if (_dynamicViewDataDictionary == null) {
_dynamicViewDataDictionary = new DynamicViewDataDictionary(() => ViewData);
}
return _dynamicViewDataDictionary;
}
} [SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly",
Justification = "This property is settable so that unit tests can provide mock implementations.")]
public ViewDataDictionary ViewData {
get {
if (_viewDataDictionary == null) {
_viewDataDictionary = new ViewDataDictionary();
}
return _viewDataDictionary;
}
set {
_viewDataDictionary = value;
}
}

可以看出ViewBag 使用ViewData(ViewDataDictionary)来保存数据,以便在view中获取相应的值。

ViewDataDictionary是实现字典接口--IDictionary<string, object>。

ViewBag--类型是net4.0才有的dynamic,该类型表示运行才知道具体的类型,编译时是无法验证类型的正确性。

好处是获取值时不需要验证值是否为null。

以下是mvc官网的解释:

MVC 2 controllers support a ViewData property that enables you to pass data to a view template using a late-bound dictionary API. In MVC 3, you can also use somewhat simpler syntax with the ViewBag property to accomplish the same purpose. For example, instead of writing ViewData["Message"]="text", you can write ViewBag.Message="text". You do not need to define any strongly-typed classes to use the ViewBag property. Because it is a dynamic property, you can instead just get or set properties and it will resolve them dynamically at run time. Internally, ViewBag properties are stored as name/value pairs in the ViewData dictionary. (Note: in most pre-release versions of MVC 3, the ViewBag property was named the ViewModel property.)

ViewData requires typecasting for complex data type and check for null values to avoid error.

ViewBag doesn’t require typecasting for complex data type.

    public ActionResult Index()

    {
ViewBag.Name = "Arun Prakash";
return View();
} public ActionResult Index()
{
ViewData["Name"] = "Arun Prakash";
return View();
} //Calling in View
@ViewBag.Name
@ViewData["Name"]

区别是复杂类型是否需要验证null,ViewData需要,ViewBag不需要。

再来个demo:

public class HomeController : Controller
{
public ActionResult Index()
{
var emp = new Employee
{ EmpID=,
Name = "Deepak",
Salary = ,
Address = "Delhi" }; ViewData["emp"] = emp;
ViewBag.Employee = emp; return View();
}
}

code for View is as follows

@model MyProject.Models.EmpModel;
@{
Layout = "~/Views/Shared/_Layout.cshtml";
ViewBag.Title = "Welcome to Home Page";
var viewDataEmployee = ViewData["emp"] as Employee; //need typcasting
}
<h2>Welcome to Home Page</h2> This Year Best Employee is!
<h4>@ViewBag.emp.Name</h4>
<h3>@viewDataEmployee.Name</h3>
</div>

While the TempData object works well in one basic scenario:

  • Passing data between the current and next HTTP requests

If you need to work with larger amounts of data, reporting data, create dashboards, or work with multiple disparate sources of data, you can use the more heavy duty ViewModel object. See my detailed blog post on ViewModels for more details on working with ViewModels.

- See more at: http://www.rachelappel.com/when-to-use-viewbag-viewdata-or-tempdata-in-asp.net-mvc-3-applications#sthash.rVx9t9N8.dpuf

While the TempData object works well in one basic scenario:

  • Passing data between the current and next HTTP requests

If you need to work with larger amounts of data, reporting data, create dashboards, or work with multiple disparate sources of data, you can use the more heavy duty ViewModel object. See my detailed blog post on ViewModels for more details on working with ViewModels.

- See more at: http://www.rachelappel.com/when-to-use-viewbag-viewdata-or-tempdata-in-asp.net-mvc-3-applications#sthash.rVx9t9N8.dpuf

Passing data between the current and next HTTP requests - See more at: http://www.rachelappel.com/when-to-use-viewbag-viewdata-or-tempdata-in-asp.net-mvc-3-applications#sthash.rVx9t9N8.dpuf

TempData is meant to be a very short-lived instance, and you should only use it during the current and the subsequent requests only!
Since TempData works this way, you need to know for sure what the next request will be, and redirecting to another view is the
only time you can guarantee this. Therefore, the only scenario where using TempData will reliably work is when you are redirecting.
This is because a redirect kills the current request (and sends HTTP status code 302 Object Moved to the client),
then creates a new request on the server to serve the redirected view.
Looking back at the previous HomeController code sample means that the TempData object could yield results differently than expected
because the next request origin can't be guaranteed. For example, the next request can originate from a completely different machine
and browser instance.

However, once the controller redirects, the ViewBag and ViewData will contain null values. If you inspect the TempData object with debugging
tools after the redirect you'll see that it is fully populated with a featured product. This is because the redirect is that only, subsequent,
request, so only it can access the TempData object without worry.

Where Is TempData Stored?

This is the part that came back to bite me. By default, TempData is stored in the session. Yes, the session! Most of the time this probably doesn’t matter to you, since as long as you get your objects back when you want them you have no reason to worry about where it was kept. However, let’s say you decide you want to switch away from the default Session-State Mode, and use State Server Mode or SQL Server Mode. These modes require that all objects stored in session be serializable. This is exactly what I did, and without knowing that TempData used the session, it was non-obvious why I started seeing session errors.

You might have noticed that I said that TempData is kept in the session by DEFAULT, meaning you are not tied to that if you decide you don’t like it that way. Let’s take a look at some of the source code to ASP.NET MVC 2 and see how things work.

ITempDataProvider and SessionStateTempDataProvider
In the System.Web.Mvc namespace you’ll find a very simple interface called ITempDataProvider that looks like this:

public interface ITempDataProvider {
IDictionary<string, object> LoadTempData(ControllerContext controllerContext);
void SaveTempData(ControllerContext controllerContext,
IDictionary<string, object> values);
}

Not much to see there. It simply defines the methods of saving and loading the dictionary. In the same namespace is SessionStateTempDataProvider which implements ITempDataProvider. When loading the dictionary out of the session, it explicitly removes it afterwards to make sure only one request gets access to it:

public class SessionStateTempDataProvider : ITempDataProvider {
internal const string TempDataSessionStateKey = "__ControllerTempData"; public virtual IDictionary<string, object> LoadTempData(ControllerContext controllerContext) {
HttpSessionStateBase session = controllerContext.HttpContext.Session; if (session != null) {
Dictionary<string, object> tempDataDictionary = session[TempDataSessionStateKey] as Dictionary<string, object>; if (tempDataDictionary != null) {
// If we got it from Session, remove it so that no other request gets it
session.Remove(TempDataSessionStateKey);
return tempDataDictionary;
}
} return new Dictionary<string, object>(StringComparer.OrdinalIgnoreCase);
} public virtual void SaveTempData(ControllerContext controllerContext, IDictionary<string, object> values) {
if (controllerContext == null) {
throw new ArgumentNullException("controllerContext");
} HttpSessionStateBase session = controllerContext.HttpContext.Session;
bool isDirty = (values != null && values.Count > ); if (session == null) {
if (isDirty) {
throw new InvalidOperationException(MvcResources.SessionStateTempDataProvider_SessionStateDisabled);
}
}
else {
if (isDirty) {
session[TempDataSessionStateKey] = values;
}
else {
// Since the default implementation of Remove() (from SessionStateItemCollection) dirties the
// collection, we shouldn't call it unless we really do need to remove the existing key.
if (session[TempDataSessionStateKey] != null) {
session.Remove(TempDataSessionStateKey);
}
}
}
} }

The controller object has a public property for the TempData provider which that uses the session provider by default:

public ITempDataProvider TempDataProvider {
get {
if (_tempDataProvider == null) {
_tempDataProvider = CreateTempDataProvider();
}
return _tempDataProvider;
}
set {
_tempDataProvider = value;
}
} protected virtual ITempDataProvider CreateTempDataProvider() {
return new SessionStateTempDataProvider();
}

参考资料:

http://stackoverflow.com/questions/4705426/whats-the-difference-between-viewdata-and-viewbag

http://www.rachelappel.com/when-to-use-viewbag-viewdata-or-tempdata-in-asp.net-mvc-3-applications

http://www.gregshackles.com/asp-net-mvc-do-you-know-where-your-tempdata-is/

asp.net mvc ViewData 和 ViewBag区别,TempData的更多相关文章

  1. ASP.net MVC+ViewData VS ViewBag

         在使用MVC框架的过程中,往界面传值,我们使用的ViewData.如ITOO部分代码图解:      当然除了ViewData,我们还能够使用同卵兄弟(ViewBag)来完毕相同的功能,详情 ...

  2. ASP.NET MVC程序传值方式:ViewData,ViewBag,TempData和Session

    转载原地址 http://www.cnblogs.com/sunshineground/p/4350216.html 在ASP.NET MVC中,页面间Controller与View之间主要有以下几种 ...

  3. ViewData、ViewBag、TempData、Session的区别与联系

    简介 这篇文章是我在学习ASP.NET MVC程序传值方式梳理总结的笔记.在ASP.NET MVC中,页面间和Controller与View之间主要有以下几种小量数据传值方式, ViewData.Vi ...

  4. [转帖]Asp.Net MVC EF各版本区别

    Asp.Net MVC EF各版本区别 https://www.cnblogs.com/liangxiaofeng/p/5840754.html 2009年發行ASP.NET MVC 1.0版 201 ...

  5. ViewData、ViewBag和TempData比较

    一.ViewData.ViewBag和TempData的定义 public dynamic ViewBag { get; } public ViewDataDictionary ViewData { ...

  6. MVC5-8 ViewData、ViewBag、TempData分析

    MVC中Contoller与视图的数据传输 后台的值显示到界面上,我们有几种方式呢.MVC给我们提供了ViewData.ViewBag.TempData.Model这几种方式,当然我们也可以用ajax ...

  7. 第三节:Action向View传值的四种方式(ViewData、ViewBag、TempData、Model)

    简  介 在前面的章节中,我们已经很清楚,MVC工作模型的流程,Controller中的Action接收到客户端的请求,处理后要将数据返回给View,那么Action中是如何将数据返回给View的,二 ...

  8. MVC ASP.NET MVC各个版本的区别

    ASP.NET MVC各个版本的区别 Net Framework4.5是不支持安装在window server 2003上,如非装请用net framework4.0; MVC1.0 publsh t ...

  9. 关于ViewData,ViewBag,TempData三者学习记录!

    关于ViewData,ViewBag,TempData三者学习分享! 1.ViewData和TempData是字典类型,赋值方式用字典方式,ViewData["Key"] . 2. ...

随机推荐

  1. 【SPFA与Dijkstra的对比】CDOJ 1961 咸鱼睡觉觉【差分约束-负权最短路径SPFA】

    差分约束系统,求最小值,跑最长路. 转自:https://www.cnblogs.com/ehanla/p/9134012.html 题解:设sum[x]为前x个咕咕中至少需要赶走的咕咕数,则sum[ ...

  2. Python_xml

    xml: 可扩展标记语言,用来标记数据,定义数据类型,主要用来传输和存储数据(和json差不多,不同语言或程序之间进行数据交换的协议) ET(xml.etree.ElementTree)中的几个类: ...

  3. JVM性能参数优化

    以上是jdk1.7的默认GC回收器 Java的gc回收的类型主要有几种 UseSerialGC, UseConcMarkSweepGC, UseParNewGC, UseParallelGC, Use ...

  4. jenkins使用教程之系统设置

    如果jenkins环境还没有搭建好的话可以看这篇文章点击查看 进入jenkins首页,点击系统管理 点击系统设置,进入系统设置界面 1.主目录,点击高级 主目录是存放Jenkins所有的文件的,工作空 ...

  5. 51Nod1868 彩色树 虚树

    原文链接https://www.cnblogs.com/zhouzhendong/p/51Nod1868.html 题目传送门 - 51Nod1868 题意 给定一颗 $n$个点的树,每个点一个 $[ ...

  6. 记录一次惊心动魄的sql去重

    )) )) url 为判重依据,保留最大id其他的数据状态改为删除状态. concat()函数,为字符串拼接函数 从外到内分析sql 第一层四个条件界定,第一个是source渠道,第二个是未删除状态, ...

  7. sqlldr的使用

    1,在公司进行预处理的时候,发现文件不能入库,而公司前辈使用的是sqlldr的技术将解析后的文件入库,前辈在测试的时候使用的是本机上的数据库(见图一),没有使用完整的远程连接oracle的正确方式,所 ...

  8. SpringMVC(十二) RequestMapping使用POJO作为参数

    将一个普通的JAVA类对象作为一个参数传入. POJO类Address: package com.tiekui.springmvc.pojo; public class Address { priva ...

  9. SQLite限定行数

    SELECT * FROM "spbak" ORDER BY intime desc limit 0,100;

  10. .NET控件名称缩写一览表 zz

    标准控件1 btn Button2 chk CheckBox3 ckl CheckedListBox4 cmb ComboBox5 dtp DateTimePicker6 lbl Label7 llb ...