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. Nginx动静分离

    动静分离 Nginx动静分离是让动态网站里的动态网页根据一定规则把不变的资源和经常变的资源区分开来,动静资源做好了拆分以后,我们就可以根据静态资源的特点将其做缓存操作,这就是网站静态化处理的核心思路. ...

  2. jenkins X实践系列(4) —— jenkins X 构建提速

    jx是云原生CICD,devops的一个最佳实践之一,目前在快速的发展成熟中.最近调研了JX,这里为第4篇,介绍如何加入jx构建和部署. builder镜像下载慢 先在一台机器上下载好,然后放到本地仓 ...

  3. 【转】使用Jasob混淆javascript代码

    在平常的web开发中,我们时常需要写一些js的类库,当我们发布自己产品的时候,不得不把源代码分发出去:但是这样就会泄露自己的代码.今天使用了一下Jasob感觉不错: 使用Jasob,我们的JavaSc ...

  4. Apache Pulsar——企业级消息订阅系统介绍

    Apache Pulsar是一款由雅虎开发的类似于Kafka的企业级消息订阅系统,在2016将其开源,由Apach基金会孵化,现在已经成长为Apache基金会的顶级项目.Pulsar在雅虎内部已经运行 ...

  5. 【转】WPF中的窗口的生命周期

    原文地址:http://www.cnblogs.com/Jennifer/articles/1997763.html WPF中的窗口的生命周期 WPF中所有窗口的基类型都是System.Windows ...

  6. html5的audio实现高仿微信语音播放效果(实际项目)

    HTML部分: <div class="tab-pane fade dialog-record" id="dialogRecord"> <vo ...

  7. sql 分隔字符串函数

    USE [tms]GO/****** Object: UserDefinedFunction [dbo].[fn_ConvertListToTable_Sort] Script Date: 2017/ ...

  8. SSL/TLS

    為 授权计算机为 SSL/TLS 安全通道建立信任关系. ServicePointManager.ServerCertificateValidationCallback += (o, c, ch, e ...

  9. python & MySQLdb(one)

    python开发过程中用到数据库无外乎MYSQL,Mangodb,redis三种,三者数据库使用可能存在差异,但在一些基础的语句使用时都是大同小异的,这阶段学习了一些基础操作,记录下 add: # - ...

  10. pyspider 启动错误遇到的一些坑

    https://blog.csdn.net/SiHann/article/details/88239892 突然接到一个项目是关于pyspider,遇到了一些小坑,百度一下发现并没有很好的解决所以研究 ...