asp.net mvc ViewData 和 ViewBag区别,TempData
ViewData 和 ViewBag都是页面级别的生命周期,TempData--Passing data between the current and next HTTP requests
TempData默认是实现方式--存在session中,所以结论很简单,能不用就不用。。要么负载时就麻烦了。
先上源码:
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
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的更多相关文章
- ASP.net MVC+ViewData VS ViewBag
在使用MVC框架的过程中,往界面传值,我们使用的ViewData.如ITOO部分代码图解: 当然除了ViewData,我们还能够使用同卵兄弟(ViewBag)来完毕相同的功能,详情 ...
- ASP.NET MVC程序传值方式:ViewData,ViewBag,TempData和Session
转载原地址 http://www.cnblogs.com/sunshineground/p/4350216.html 在ASP.NET MVC中,页面间Controller与View之间主要有以下几种 ...
- ViewData、ViewBag、TempData、Session的区别与联系
简介 这篇文章是我在学习ASP.NET MVC程序传值方式梳理总结的笔记.在ASP.NET MVC中,页面间和Controller与View之间主要有以下几种小量数据传值方式, ViewData.Vi ...
- [转帖]Asp.Net MVC EF各版本区别
Asp.Net MVC EF各版本区别 https://www.cnblogs.com/liangxiaofeng/p/5840754.html 2009年發行ASP.NET MVC 1.0版 201 ...
- ViewData、ViewBag和TempData比较
一.ViewData.ViewBag和TempData的定义 public dynamic ViewBag { get; } public ViewDataDictionary ViewData { ...
- MVC5-8 ViewData、ViewBag、TempData分析
MVC中Contoller与视图的数据传输 后台的值显示到界面上,我们有几种方式呢.MVC给我们提供了ViewData.ViewBag.TempData.Model这几种方式,当然我们也可以用ajax ...
- 第三节:Action向View传值的四种方式(ViewData、ViewBag、TempData、Model)
简 介 在前面的章节中,我们已经很清楚,MVC工作模型的流程,Controller中的Action接收到客户端的请求,处理后要将数据返回给View,那么Action中是如何将数据返回给View的,二 ...
- MVC ASP.NET MVC各个版本的区别
ASP.NET MVC各个版本的区别 Net Framework4.5是不支持安装在window server 2003上,如非装请用net framework4.0; MVC1.0 publsh t ...
- 关于ViewData,ViewBag,TempData三者学习记录!
关于ViewData,ViewBag,TempData三者学习分享! 1.ViewData和TempData是字典类型,赋值方式用字典方式,ViewData["Key"] . 2. ...
随机推荐
- T4模版自动生成MSSQL实体类
在Model层建立ModelAuto.ttinclude文件 <#@ assembly name="System.Core"#> <#@ assembly nam ...
- 修改element ui 默认样式最好的解释
KedAyAyA 17年10月 https://forum.vuejs.org/t/elementui/19171/5 首先添加了scoped的style标签会在vue-loader里进行处理 所谓的 ...
- Java程序编译和运行过程之 一个对象的生命之旅(类加载和类加载器)
Java程序从创建到运行要经过两个大步骤 1:源文件(.java)由编译器编译成字节码ByteCode(.class) 2:字节码由Java虚拟机解释并运行 源文件编译成字节码,主要分成两个部分: 1 ...
- autio的自动播放问题
最近做年会相关内容,背景音乐插入了,电脑上没问题,移动版就出事了,下面做一下记录 <audio src="" autoplay="autoplay" l ...
- POJ 2488 A Knight's Journey-dfs
题目链接:http://poj.org/problem?id=2488 题目解读:首先得弄清楚国际象棋中关于“马走日”的规则,如上图中的马,它的下一步的走法有8中,所以对每一个位置的马,它所能走的8个 ...
- POJ 1200 Crazy Search 【hash】
<题目链接> 题目大意: 给定n,nc,和一个字符串,该字符串由nc种字符组成,现在要你寻找该字符串中长度为n的子字符串有多少种. 解题分析: 因为要判重,所以讲这些字符串hash一下,将 ...
- Django模板之通用模板的使用
Django模板之通用模板的使用 转载:https://code.ziqiangxuetang.com/django/django-template.html 我们做网站有一些通用的部分,比如 导航, ...
- shell编程第二天
- SpringBoot学习历程
新年新气象,更新了一下本人所有写的关于SpringBoot的文章目录,感谢大家长期以来的支持,在接下来的日子还会不定期的进行更新. 入门 使用IntelliJ Idea新建SpringBoot项目 S ...
- 改变字体大小实现自适应之js方案A
一.元素大小有两种写法 1.写结果:设计师给的移动端页面sketch设计稿一般是750px宽度,在sublime编辑器里,设置cssrem或rem-unit插件为56px的字体大小.做页面时,设计稿是 ...