【MVC4 之 ViewData ViewBag TempData】
ViewData
(一个字典集合类型):传入的key必须是string类型,可以保存任意对象信息,特点:它只会存在这次的HTTP的要求中而已,并不像session可以将数据带到下一个Http要求。
ViewData.Model:由于viewdata在传入的时候属于弱类型,也就是在ViewData里特定键值的类型永远是object通用对象类型,传给view使用之后,还必须通过转型才能进一步使用,不太方便。 eg: public ActionResult Index(){ var data=GetDataFromDB();
ViewData.Model=data; return View();
或者直接return view(data);一样,都是将viewdata.model传给view使用 }
当你通过viewdata.Model传递数据到检视页面,在检视页面中可以用@model声明一个该检视页面专属的数据模型型别,声明后就可以在检视页面中取用@Model对象,而@Model对象就会拿控制器里设置好的ViewData.Model数据,并自动转型为@model声明的型别。
ViewBag
(dynamic动态类型:是.NET Framework4.0的新功能): 定义在System.Web.Mvc.ControllerBase抽象类中,优点是可以少输入几个字符: eg: ViewData["Message"]="更改此模板即可开始着手进行您的mvc应用程序"; || ViewBag.Message="更改此模板即可开始着手进行您的mvc应用程序";
TempData
数据结构与ViewData一样是字典型别,但TempData的类型是TempDataDictionary,不过还有一点不同的地方,在于它的内部是使用Session(默认,也可以更改为使用Cookie)来保存信息,“Temp”表示暂存,但是保存在TempData中的数据回暂存多久呢?答案是:一次网页要求。
一次网页要求:在窗体数据送出到以下Action保存,如果发生数据库新增失败的消息,我们会希望这次送出的数据可以保留到下一页,此时,就会将这个只希望出现一次的消息保存在TempData中,并在下一页进行取用。
eg:在更新数据库时发生失败后,会先将这次收到的Message数据保存到TempData["PostedMessage"]变量里,
然后转回到了Create这个Action
[httpPost] public ActionResult Create(Message msg) {
if(!UpdateMessageToDB(msg)){
tempData["aaa"]=msg;
return RedirectToAction("Create");
}
else{ return RedirectToAction("Index"); }
}
[httpGet] public ActionResult Create() {
string data=TempData["aaa"] as Message;
return View(Data);
}
此时重新回到Create动作,数据从tempdata中再次读出,并再次传递到create检视页面,当这次mvc生命周期退出的前一刻,由于mvc会记录tempdata已经被读取过,因此,在这次http要求退出钱就会将TempData["aaa"]删除。
一般来说,在action用到TempData来保存数据时,
通常会使用RedirectResult或RedirectToRouteResult来当成Action回传类型(Redirect,RedirectToAction,RedirectToRoute辅助方法),
如果你的action不是回传这两个的话很可能导致TempData提前消失
ViewData ViewData ViewBag 的特点和使用场景比较
1. TempData:类型是字典的键值对结构
特点:值只能取一次。保存在Session中,Controller每次执行请求的时候,会从Session中先获取TempData,而后清除 Session,获取完TempData数据,虽然保存在内部字典对象中,但是其集合中的每个条目访问一次后就从字典表中删除。具体代码层 面,TempData获取过程是通过SessionStateTempDataProvider.LoadTempData方法从 ControllerContext的Session中读取数据,而后清除Session,故TempData只能跨Controller传递一次。每次请求结束后,TempData的生命周期也就结束了 使用场景:
(1)TempData 一般用于临时的缓存内容或抛出错误页面时传递错误信息,可以将TempData 在使用之前存储到相应的 ViewData 中以备循环使用
(2)从一个action跳转到另一个action(可以跨controller),并且需要携带参数时使用。例如从用户分组action跳转到用户列表,传递的参数为分组ID,在用户列表页显示该分组ID的用户。
2.ViewData:类型是字典的键值对结构
特点:生命周期和View相同,仅对当前View有效。ViewData只会在一次HTTP请求中有效,当这次请求结束后,就会自动清空其值。
使用场景:可以用在Action向View传递数据。但向页面传值最常用的是向View传递Model,这本身就是MVC的意义所在。
3.ViewBag:ViewBag存放的不是键值对,而是dynamic动态类型
特点:和ViewData生命周期相同,也是对但前View有效
ViewBag向页面传值,可以用
window.searchDataDate = @Html.Raw(ViewBag.date);
接收,在任何该页面引用的js文件里都可以引用该值。
二 后台使用Request接收参数是,如果书用的是GET方式,可以使用
Request.QueryString["key"]
如果使用的的是POST方式,上面的方法无法获取,只能用下面的语句获取
Request.Params.Get["key"]
三 更简洁的方式
return RedirectToAction("MemberManager", "Shop", new { id = Session["shopid"] });
MemberManager:页面的Action;Shop:Controller名称;id:要传的参数名;Session["shopid"]:要传的参数!
ASP.NET MVC中的两个Action之间值的传递--TempData
一. ASP.NET MVC中的TempData
在ASP.NET MVC框架的ControllerBase中存在一个叫做TempData的Property,它的类型为TempDataDictionary,顾名思义是一个字典类。TempData在ASP.NET MVC中的作用是:可用于在Action执行过程之间传值。简单的说,你可以在执行某个Action的时候,将数据存放在TempData中,那么在下一次Action执行过程中可以使用TempData中的数据。
如:

1 public ActionResult Index()
2 {
3 this.TempData["MyNane"] = "XiaoMing";
4 return View();
5 }
6 public ActionResult Index2()
7 {
8 string MyName=this.TempData["MyNane"] as string;
9 return View();
10 }

上面的代码中,Index()给TempData添加了一个键值对,假设我们先请求Index这个Action,接着请求Index2这个Action,那么在Index2中,我们便可以得到之前添加到TempData的键值对。有趣的是,这时如果再次请求Index2,那么从TempData中读到的MyName的值会是null。于是,我们需要了解TempData的生命周期。
二. TempData的生命周期
我们知道Http是无状态的,为什么TempData可以在两次请求之前传递数据呢?很明显,这个数据必定是已某种形式保存了。查看Controller类的源代码,很容易的找到了我们想要的东西:

1 protected override void ExecuteCore()
2 {
3 TempData.Load(ControllerContext, TempDataProvider);
4 try
5 {
6 string actionName = RouteData.GetRequiredString("action");
7 if (!ActionInvoker.InvokeAction(ControllerContext, actionName))
8 {
9 HandleUnknownAction(actionName);
10 }
11 }
12 catch (Exception)
13 {
14
15 TempData.Save(ControllerContext, TempDataProvider);
16 }
17 }

从上面的代码可以看出,每次在执行Action之前,都要调用一下TempData.Load()方法,执行完Action之后,再调用一下TempData.Save()方法。另外这里还有一个重要成员TempDataProvider。
阅读了相关源代码之后,真相大白了。
TempData.Load()

1 public void Load(ControllerContext controllerContext, ITempDataProvider tempDataProvider)
2 {
3 IDictionary<string, object> providerDictionary = tempDataProvider.LoadTempData(controllerContext);
4 _data = (providerDictionary != null) ? new Dictionary<string, object>(providerDictionary, StringComparer.OrdinalIgnoreCase) :
5 new Dictionary<string, object>(StringComparer.OrdinalIgnoreCase);
6 _initialKeys = new HashSet<string>(_data.Keys);
7 __modifiedKeys.Clear();
8 }

TempData.Save()

1 public void Save(ControllerContext controllerContext, ITempDataProvider tempDataProvider)
2 {
3 if (_modifiedKeys.Count > 0)
4 {
5
6 // Apply change tracking.
7 foreach (string x in _initialKeys)
8 {
9 if (!_modifiedKeys.Contains(x))
10 {
11 _data.Remove(x);
12 }
13 }
14
15 // Store the dictionary
16 tempDataProvider.SaveTempData(controllerContext, _data);
17 _modifiedKeys.Clear();
18 }
19 }

TempDataProvider用于暂存数据。在TempData.Load()方法中,TempDataProvider中保存的数据会被读到TempData中,供Action调用过程中使用。Action执行完后,TempData.Save()所作的事情则是,移除TempData中任何没有被更新的键值对,然后再将TempData中的数据保存,供下一次调用使用(注:也就是说,只有更新过的,以及新添加的键值对才能再下次request中继续使用)。为什么TempData中的数据需要迅速被清除呢?很简单,节约内存嘛。
三. ITempDataProvider
前面提到的TempDataProvider是Controller的一个Property,它的定义是这样的:

1 public ITempDataProvider TempDataProvider
2 {
3 get
4 {
5 if(_tempDataProvider==null){
6 _tempDataProvider = new SessionStateTempDataProvider();
7 }
8 return _tempDataProvider;
9 }
10 set
11 {
12 _tempDataProvider = value;
13 }
14 }

这里我们看到了一个默认实现的SessionStateTempDataProvider类。也就是说,默认情况下,ASP.NET MVC通过SessionStateTempDataProvider来保存TempData的数据。很明显,数据是存在Session中的,也就是说,如果你禁用SessionState,那么你的页面就报异常了。
ASP.NET MVC生来就是被设计为易扩展的,我们可以很容易通过实现自己的ITempDataProvider类来替换这个默认的SessionStateTempDataProvider。需要注意的是,TempDataProvider存放的数据必需具有用户独立性。
ITempDataProvider接口定义非常简单:
1 public interface ITempDataProvider
2 {
3 IDictionary<string, object> LoadTempData(ControllerContext controllerContext);
4 void SaveTempData(ControllerContext controllerContext, IDictionary<string, object> values);
5 }
在MvcFutures中,你也可以找到一个CookieTempDataProvider,提供了将TempData存储在Cookie中的实现。
【MVC4 之 ViewData ViewBag TempData】的更多相关文章
- ViewData ViewBag TempData
ViewData(一个字典集合类型):传入的key必须是string类型,可以保存任意对象信息,特点:它只会存在这次的HTTP的要求中而已,并不像session可以将数据带到下一个Http要求. ...
- ASP.NET MVC4中ViewBag、ViewData和TempData的使用和区别
一.说明 本文章主要是讲解asp.net mvc中ViewBag.ViewData和TempData的使用和区别,ViewBag.ViewData和TempData常常用于将action方法中的数据传 ...
- MVC3中 ViewBag、ViewData和TempData的使用和区别
在MVC3开始,视图数据可以通过ViewBag属性访问,在MVC2中则是使用ViewData.MVC3中保留了ViewData的使用.ViewBag 是动态类型(dynamic),ViewData 是 ...
- ViewBag、ViewData和TempData的使用和区别
在MVC3开始,视图数据可以通过ViewBag属性访问,在MVC2中则是使用ViewData. MVC3中保留了ViewData的使用. ViewBag 是动态类型(dynamic),ViewData ...
- MVC3+中 ViewBag、ViewData和TempData的使用和区别
在MVC3开始,视图数据可以通过ViewBag属性访问,在MVC2中则是使用ViewData.MVC3中保留了ViewData的使用.ViewBag 是动态类型(dynamic),ViewData 是 ...
- MVC中 ViewBag、ViewData和TempData区别
MVC3中 ViewBag.ViewData和TempData的使用和区别 public dynamic ViewBag { get; } public ViewDataDictionary View ...
- MVC3中 ViewBag、ViewData和TempData的使用和区别(不是自己写的)
(网上抄的,并未消化)在MVC3开始,视图数据可以通过ViewBag属性访问,在MVC2中则是使用ViewData.MVC3中保留了ViewData的使用.ViewBag 是动态类型(dynamic) ...
- MVC3中 ViewBag、ViewData和TempData的使用和区别(转发:汴蓝)
MVC3中 ViewBag.ViewData和TempData的使用和区别 在MVC3开始,视图数据可以通过ViewBag属性访问,在MVC2中则是使用ViewData.MVC3中保留了ViewD ...
- ViewBag、ViewData和TempData使用方法、区别与联系
一.区别与联系 ViewData 和 TempData 都可以传递弱类型数据,区别如下:TempData 只在当前 Action 中有效,生命周期和 View 相同:保存在Session中,Contr ...
随机推荐
- 【转】Git与Repo入门----不错
原文网址:http://www.cnblogs.com/angeldevil/p/3238470.html Git与Repo入门 版本控制 版本控制是什么已不用在说了,就是记录我们对文件.目录或工 ...
- Deploy a Sharded Cluster
Start the Config Server Database Instances for example : mongod --configsvr --dbpath <path> - ...
- 【shell】构造并遍历二位数组的一种用法
参考shell数组的部分操作用法,实现了构造和遍历二维数组的一种方式,具体如下: #数组元素以空格分割 sites=("www.a.com www.b.com www.c.com www.d ...
- hdu 5656 CA Loves GCD(dp)
题目的意思就是: n个数,求n个数所有子集的最大公约数之和. 第一种方法: 枚举子集,求每一种子集的gcd之和,n=1000,复杂度O(2^n). 谁去用? 所以只能优化! 题目中有很重要的一句话! ...
- ASP.net ListItem Attributes 属性回传丢失的解决方案
该方法为网上整理 1. 新继承一个列表控件 新控件中重写两个方法: using System; using System.Collections.Generic; using System.Linq; ...
- Android设备内存和SD卡操作工具类
package cc.c; import java.io.File; import java.util.List; import android.os.StatFs; import java.io.F ...
- HDU 1248 寒冰王座(全然背包:入门题)
HDU 1248 寒冰王座(全然背包:入门题) http://acm.hdu.edu.cn/showproblem.php?pid=1248 题意: 不死族的巫妖王发工资拉,死亡骑士拿到一张N元的钞票 ...
- ubuntu下30天自制操作系统还在继续学习中
操作系统还在学习中,进度不是非常确定,近期学习到了第13天的中部,由于把ucgui移植上去花了一点时间. 同一时候为了方便代码的兴许管理和分享,也为了学习github的代码管理使用思想, 所以建立了一 ...
- [Immutable + AngularJS] Use Immutable .List() for Angular array
const stores = Immutable.List([ { name: 'Store42', position: { latitude: 61.45, longitude: 23.11, }, ...
- phpStudy + JspStudy 2014.10.02 下载
phpStudy + JspStudy 2014.10.02 下载 目标:让天下没有难配的php环境. phpStudy Linux版&Win版同步上线 支持Apache/Nginx/Teng ...