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. 【Android】ImageView ScaleType属性值

    ImageView.ScaleType / android:scaleType值的意义区别: CENTER /center 按图片的原来size居中显示,当图片长/宽超过View的长/宽,则截取图片的 ...

  2. 没有IDE的日子

    没有QT Creator,没有VS2008,没有Eclipse,也没有KDevelop,忘掉一切IDE. 好吧,现在我只有Vim了,可我跟Vim不熟. Vim魅力四射,光芒万丈,高高在上,她就是传说中 ...

  3. 设备arduino的编译目录

    1.arduino-0023\lib\preferences.txt 修改 #build.path=build build.path=d:\build_wpadk d:\build_wpadk为自定义 ...

  4. Zabbix监控Low level discovery实时监控网站URL状态

    今天我们来聊一聊Low level discovery这个功能,我们为什么要用到loe level discovery这个功能呢? 很多时候,在使用zabbix监控一些东西,需要对类似于Itens进行 ...

  5. day11 装饰器---函数的使用方法

    这个是一个难点,以后面试会经常出现的,要搞懂! 装饰器升级版,进阶内容1: def outer(flag): def wrapper(func): def inner(*args,**kwargs): ...

  6. RBM:深度学习之Restricted Boltzmann Machine的BRBM学习+LR分类—Jason niu

    from __future__ import print_function print(__doc__) import numpy as np import matplotlib.pyplot as ...

  7. hdu 1237 简单计算器 (表达式求值)【stack】

    <题目链接> 题目大意: 读入一个只包含 +, -, *, / 的非负整数计算表达式,计算该表达式的值.  Input测试输入包含若干测试用例,每个测试用例占一行,每行不超过200个字符, ...

  8. hdu 3499 flight 【分层图】+【Dijkstra】

    <题目链接> 题目大意: 现在给你一些点,这些点之间存在一些有向边,每条边都有对应的边权,有一次机会能够使某条边的边权变为原来的1/2,求从起点到终点的最短距离. 解题分析: 分层图最短路 ...

  9. vue-cli@3.x初体验之前篇-回顾vue-cli@2.x创建项目的流程

    模拟实际工作中的操作,假如新开启了一个vue项目,可以先看看上篇博文中的git操作,新建空仓库vue-demo,并拉取到本地,创建本地dev分支后 1. 全局安装vue-cli yarn global ...

  10. Github入门操作实录

    到目前为止,我已经工作快5年了,这5年最大的感受就是,框架什么的并不难,只要知道api,就能用起来,一开始会遇到一点问题,但是天下的框架都大同小异,无非是jar包,配置文件,模板代码,jar包可以使用 ...