025-ViewData、ViewBag与TempData概述
Action向View传递数据很简单,方式也很多,最直接的就是我们向View传递Model,这本身就是MVC的意义所在。如果是显示一些消息,像是错误信息,可以使用ViewData、ViewBag、TempData等。
1. ViewData
当你使用ViewResult来运行结果时,可以在Action里面利用ControllerBase类别中的ViewData属性来保存数据,以便这些数据可以传递给View使用。ViewData就是一个字典,它存放的是键值对。在设置ViewData属性时,传入的key必须为字符串类型,而属性部分可以保存任意对象信息。
ViewData的特性是它只会存在这次的HTTP请求中,而不会像Session将数据带到下一个HTTP请求。
public class HomeController:Controller
{
public ActionResult Index()
{
ViewData["message"]="hello";
return View();
}
}
在Index视图中可以访问该message。
<p>@ViewData["message"]</p>
2. ViewData.Model
ViewDataDictionary其实就是一个字典对象,在ASP.NET MVC里做出了几个扩充属性,其中包括Model、ModelMetadata与ModelState这三个。
由于使用ViewData字典在传入时属于“弱类型”的方式保存,也就是在ViewData里特定键值的类型永远是object通用对象类型,传给View使用之后,还必须通过转型才能进一步使用,所以用起来不太方便。
在ASP.NET MVC的View相关技术里,可以将特定视图页面声明为某种类型,让整个视图页面参考特定类型,并且让Controller传来的Model数据直接自动转型为View所声明的类型,而这个从Controller传来的Model数据就是通过ViewData.Model传过来的。
以下程序代码演示可以将数据通过ViewData.Model传递给View的Model使用:
public ActionResult Index()
{
var data = GetDataFromDB();
ViewData.Model = data;
return View();
}
上述这段程序代码与以下这段程序代码的结果是完全一样的,都是将ViewData.Model传给View页面使用:
public ActionResult Index()
{
var data = GetDataFromDB();
return View(data);
}
从VS2012的快捷提示中,可以发现ViewData.Model也是object类型,为什么说这个跟“强类型”有关呢?

当你通过ViewData.Model传递数据到视图页面,在视图页面里可以也用@model声明一个该视图页面专属的数据模型类型,声明后就可以在视图页面中取用@Model对象,而@Model对象就会拿Controller里设置好的ViewData.Model数据,并且自动转型为@model声明的类型。

声明完成后,我们在视图页面就可以以具有类型@Model的对象进行开发,享受VS2012里使用Intellisense的方便性。

3. ViewBag
ViewBag的使用就相当于ViewData,它被声明为一个dynamic动态类型,并且属性是一个传入ViewData的DynamicViewDataDictionary动态ViewData字典。例如以下ViewData的写法:
ViewData["Message"]="更改此模板即可开始着手进行您的ASP.NET MVC应用程序。"
换成ViewBag的写法则如下:
ViewBag.Message="更改此模板即可开始着手进行您的ASP.NET MVC应用程序。";
严格上来说,ViewBag并没有什么特殊之处,因为所有对ViewBag属性的任何访问动作,最终都还是对ViewData来进行操作,唯一的差别仅在于ViewBag是dynamic动态类型而已,优点是可以少输入几个字符。此外VewBag最大的优点就是它不需要转型就可以使用它里面的值,但ViewData需要这样:
string message = ViewData["message"] as string;
ViewBag就是封装了的ViewData,它是顺应C#4的dynamic关键字而诞生的。它可以让我们像是属性访问一样检索字典中的值,这样更加自然,这也是C#所倡导的:"可以读出来的代码"。
ViewBag在使用上与ViewData并没有孰优孰劣的说法,但是可以肯定,ViewBag比ViewData要慢,但这个真心可以忽略。值得注意的是,ViewBag可以直接访问存储在ViewData里面的数据(因为它本来就只是封装了的ViewData)。但是,像是这样:
ViewData["Message hehe"] = "Hello, Word";
ViewBag就有心无力了。更加重要的是,ViewBag无法作为扩展方法的参数,因为编译器为了确保所选择的扩展方法是正确的,编译时必须知道参数的真正类型,所以,HTML辅助方法无法使用ViewBag。
4.TempData
TempData的数据结构与ViewData一样都是字典类型,但TempData的类型是TempDataDictionary。TempData,顾名思义,就是临时数据。TempData保存在Session中,Controller每次请求的时候都会从Session中获取TempData,然后清除Session。基于这样的事实,在每次请求结束后,TempData的生命周期也就结束了。
不过,TempData还是有那么一点不同的地方,在于它的内部是使用Session来保存信息,更有趣的是它的名称与特性。“Temp”是暂存的意思,但是保存在TempData中的信息会暂存多久呢?答案是:一次网页请求。网上有一句话:TempData至多之只能通过一次Controller传递,假设我们的Controller是跳转到下一个Controller,以此类推,在最后一个Controlle相应的视图上,的确可以获得该TempData。但是,这并不是说TempData已经跨请求传递了,这依然只是一次请求,至于是否是跨Controller传递,我认为不是,所谓的通过Controller传递,是指将TempData传递给View,在上面的例子中,只有最后的Controller才会将该TempData传递给View,所以,TempData的确是只能通过一次Controller传递。
TempData也可以在Action之间传递的,像是这样:

public ActionResult Index()
{
TempData["T1"]="123";
//string tmp = TempData["T1"].ToString();
return View();
} public ActionResult About()
{
ViewData["T1"] = TempData["T1"];
return View();
}

以上代码,能在About动作中使用ViewData["T1"]。但如果在Index动作中添加string tmp = TempData["T1"].ToString();,则程序出错。也就是说,要使该行为正确,也就是TempData能够被传递给另一个Action,Index操作对应的视图就不能使用TempData,因为一旦使用就相当于一次请求,那么TempData中的值就会被清空。
TempData是存储在Session中,但这个并不是绝对的,我们可以改变TempData的存储地方,只要实现ITempDataProvider这个接口就行,但一般情况没有必要这么做。
025-ViewData、ViewBag与TempData概述的更多相关文章
- 几句话说明 .NET MVC中ViewData, ViewBag和TempData的区别
ViewData和TempData是字典类型,赋值方式用字典方式, ViewData["myName"] ViewBag是动态类型,使用时直接添加属性赋值即可 ViewBag.my ...
- MVC控制器传递多个Model到视图,使用ViewData, ViewBag, 部分视图, TempData, ViewModel, Tuple
从控制器传递多个Model到视图,可以通过ViewData, ViewBag, PartialView, TempData, ViewModel,Tuple等,本篇逐一体验.本篇源码在github. ...
- MVC5-8 ViewData、ViewBag、TempData分析
MVC中Contoller与视图的数据传输 后台的值显示到界面上,我们有几种方式呢.MVC给我们提供了ViewData.ViewBag.TempData.Model这几种方式,当然我们也可以用ajax ...
- 译:什么是ViewData的, ViewBag和TempData? - MVC为当前和后续请求之间传递数据的三种方法
译文出处:http://www.codeproject.com/Articles/476967/WhatplusisplusViewData-cplusViewBagplusandplusTem AS ...
- ASP.NET MVC程序传值方式:ViewData,ViewBag,TempData和Session
转载原地址 http://www.cnblogs.com/sunshineground/p/4350216.html 在ASP.NET MVC中,页面间Controller与View之间主要有以下几种 ...
- ViewData,ViewBag和TempData
ViewData ViewBag TempData 类型 字典 Dynamic TempDataDictionary 出生时间 MVC1 MVC3 框架版本 .net3.5 .net4.0 ...
- 【MVC4 之 ViewData ViewBag TempData】
ViewData (一个字典集合类型):传入的key必须是string类型,可以保存任意对象信息,特点:它只会存在这次的HTTP的要求中而已,并不像session可以将数据带到下一个Http要求. V ...
- 浅谈 MVC中的ViewData、ViewBag和TempData
ViewBag和TempData的区别 ViewData ViewBag 它是Key/Value字典集合 它是dynamic类型对像 从Asp.net MVC 1 就有了 ASP.NET MVC3 才 ...
- 第三节:Action向View传值的四种方式(ViewData、ViewBag、TempData、Model)
简 介 在前面的章节中,我们已经很清楚,MVC工作模型的流程,Controller中的Action接收到客户端的请求,处理后要将数据返回给View,那么Action中是如何将数据返回给View的,二 ...
随机推荐
- C# this.invoke()作用 多线程操作UI
Invoke()的作用是:在应用程序的主线程上执行指定的委托.一般应用:在辅助线程中修改UI线程( 主线程 )中对象的属性时,调用this.Invoke(); //测试的窗体 public class ...
- null&this&super&向上转型
向上转型:父类声明子类实例化对象 例如A是父类 B是子类 1 : 实际上是父类的对象但将会丢失子类没有的父类方法 ,如果调用方法 将会调用子类重写的父类方法 2:上转型对象不能调用子类新增 ...
- 关于cookie的清除
关于cookie的清除 设置cookie时若指定了目录,那么在删除cookie时也必须指定相同的目录,如此才可以删除之前设置的cookie的值!!!!!!!!!
- 协方差Covariance的表述推导
今天想了一下关于概率论的一维数据期望.方差以及高维数据的矩阵表示,突然想到为什么在一维中 方差的表示为:V(x) = E((x-E(x))2) 而到了高维,这样的表述就成了协方差呢?V(X) = E( ...
- Scanner
/* next()与nextLine()区别 next(): 1.一定要读取到有效字符后才可以结束输入. 2.对输入有效字符之前遇到的空白,next()方法会自动将其去掉. 3.只有输入有效字符后才将 ...
- [C程序设计语言]第一部分
声明:原创作品,转载时请注明文章来自SAP师太技术博客( 博/客/园www.cnblogs.com):www.cnblogs.com/jiangzhengjun,并以超链接形式标明文章原始出处,否则将 ...
- Xcode error: conflicting types for 'XXXX'
问题描述:在main方法中调用了一个写在main方法后面的方法,比如: void main(){ A(); } void A(){} Xcode编译后就报错:conflicting types for ...
- winform打开唯一窗体、构造函数传值
制作登入窗体: 制作一个登陆窗体,实现点击按钮关闭此窗体并打开另一个窗体 直接在按钮点击事件中,实例化一个想要打开的窗体 使用show方法打开,并把登陆窗体的visible属性改为false Form ...
- sscanf的用法(转)
队长做上海邀请赛的I题时遇到一个棘手的问题,字符串的处理很麻烦,按传统的gets全部读入的话还要做N多处理,太浪费时间. 回来之后搜了一下sscanf的用法发现可以很好的解决这一类问题,各种百度,转来 ...
- django连接mysql自动同步生成数据表
python manage.py makemigrations python manage.py migrate 如果是 Django 不主动提示创建管理员(Django 1.9不提示)用下面的命令创 ...