本文转自: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. 1 public ActionResult Index()
  2. 2 {
  3. 3 this.TempData["MyNane"] = "XiaoMing";
  4. 4 return View();
  5. 5 }
  6. 6 public ActionResult Index2()
  7. 7 {
  8. 8 string MyName=this.TempData["MyNane"] as string;
  9. 9 return View();
  10. 10 }

上面的代码中,Index()给TempData添加了一个键值对,假设我们先请求Index这个Action,接着请求Index2这个Action,那么在Index2中,我们便可以得到之前添加到TempData的键值对。有趣的是,这时如果再次请求Index2,那么从TempData中读到的MyName的值会是null。于是,我们需要了解TempData的生命周期。

二. TempData的生命周期

我们知道Http是无状态的,为什么TempData可以在两次请求之前传递数据呢?很明显,这个数据必定是已某种形式保存了。查看Controller类的源代码,很容易的找到了我们想要的东西:

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

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

阅读了相关源代码之后,真相大白了。

TempData.Load()

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

TempData.Save()

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

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

三. ITempDataProvider

前面提到的TempDataProvider是Controller的一个Property,它的定义是这样的:

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

这里我们看到了一个默认实现的SessionStateTempDataProvider类。也就是说,默认情况下,ASP.NET MVC通过SessionStateTempDataProvider来保存TempData的数据。很明显,数据是存在Session中的,也就是说,如果你禁用SessionState,那么你的页面就报异常了。

ASP.NET MVC生来就是被设计为易扩展的,我们可以很容易通过实现自己的ITempDataProvider类来替换这个默认的SessionStateTempDataProvider。需要注意的是,TempDataProvider存放的数据必需具有用户独立性。

ITempDataProvider接口定义非常简单:

  1. 1 public interface ITempDataProvider
  2. 2 {
  3. 3 IDictionary<string, object> LoadTempData(ControllerContext controllerContext);
  4. 4 void SaveTempData(ControllerContext controllerContext, IDictionary<string, object> values);
  5. 5 }

在MvcFutures中,你也可以找到一个CookieTempDataProvider,提供了将TempData存储在Cookie中的实现。

 
 
分类: ASP.Net_MVC

[转]ASP.NET MVC中的两个Action之间值的传递--TempData的更多相关文章

  1. ASP.NET MVC中的两个Action之间值的传递--TempData

    一. ASP.NET MVC中的TempData 在ASP.NET MVC框架的ControllerBase中存在一个叫做TempData的Property,它的类型为TempDataDictiona ...

  2. ASP.NET MVC中从前台页面视图(View)传递数据到后台控制器(Controller)方式

    方式一: 数据存储模型Model:此方式未用到数据存储模型Model,仅简单的字符串string型数据传递 前台接收显示数据视图View: <div style="height:300 ...

  3. Asp.net MVC中Html.Partial, RenderPartial, Action,RenderAction 区别和用法(mvc部分视图的添加)

    Partial 和RenderPartial:这两个的性质都是一样, 只指把一个个View给镶入进来, 只是回传值有点不一样Partial 回传的一个Object (MvcHtmlString), 回 ...

  4. Asp.net MVC中Html.Partial, RenderPartial, Action,RenderAction 区别和用法

    Partial 和RenderPartial:这两个的性质都是一样, 只指把一个个View给镶入进来, 只是回传值有点不一样Partial 回传的一个Object (MvcHtmlString), 回 ...

  5. Asp.net MVC中Html.Partial, RenderPartial, Action,RenderAction 区别和用法【转发】

    Html.partial和RenderPartial的用法与区别Html.partial和RenderPartial都是输出html片段,区别在于Partial是将视图内容直接生成一个字符串并返回(相 ...

  6. [转]Asp.net MVC中Html.Partial, RenderPartial, Action,RenderAction 区别和用法

    本文转自:http://www.cnblogs.com/gesenkof99/archive/2013/06/03/3115052.html Partial 和RenderPartial:这两个的性质 ...

  7. 转载ASP.NET MVC 中@Html.Partial,@Html.Action,@Html.RenderPartial,@Html.RenderAction区别

    对这四个的区别做一个总结,清理一下思路,方便以后使用: 1.带有Render的方法返回值是void,在方法内部进行输出:不带的返回值类型为MvcHtmlString,所以只能这样使用:     @Ht ...

  8. asp.net MVC 中@Html.Partial,@Html.Action,@Html.RenderPartial,@Html.RenderAction区别

    @Html.Action:需要有对应的Action,并且Action方法有返回值.(注:处理完业务逻辑同时,也需要返回所需值) @{Html.RenderAction}:需要有对应的Action,Ac ...

  9. 关于 ASP.NET MVC 中的视图生成

    在 ASP.NET MVC 中,我们将前端的呈现划分为三个独立的部分来实现,Controller 用来控制用户的操作,View 用来控制呈现的内容,Model 用来表示处理的数据. 从控制器到视图 通 ...

随机推荐

  1. 「CF 600E」 Lomsat gelral

    题目链接 戳我 \(Describe\) 给出一棵树,每个节点有一个颜色,求每个节点的子树中颜色数目最多的颜色的和. \(Solution\) 这道题为什么好多人都写的是启发式合并,表示我不会啊. 这 ...

  2. 跳转iPhone设置页面,绕过审核

    1.问题描述 跳转iPhone设置页面之前都是通过 App-Prefs:root=WIFI 来跳转,但是2018年6月废弃了这个函数,被认为是私有函数,审核会被拒绝. 有心人采用了字符串转码的方式来规 ...

  3. 1221: Fibonacci数列 [数学]

    1221: Fibonacci数列 [数学] 时间限制: 1 Sec 内存限制: 128 MB 提交: 116 解决: 36 统计 题目描述 Fibonacci数列的递推公式为:Fn=Fn-1+Fn- ...

  4. April Fools Day Contest 2019 A. Thanos Sort

    A. Thanos Sort time limit per test 1 second memory limit per test 256 megabytes input standard input ...

  5. 用Python写一个随机密码生成器

    # /bin/python3 import sys import time import random strs = [ i for i in range(32,128) ] #产生密码的ASCII码 ...

  6. php代码审计5审计命令执行漏洞

    命令执行漏洞:通过易受攻击的应用程序在主机操作系统上执行任意命令,用户提供的数据(表单,cookie,http头等)未过滤 挖掘思路:用户能够控制函数输入,存在可执行代码的危险函数 命令执行和代码执行 ...

  7. webstorm激活服务器地址

    2017.1.4版本可用 http://idea.imsxm.com/

  8. pg_basebackup命令解析

    pg_basebackup命令首先解析输入的参数,再调用BaseBackup()函数进行备份处理. 在BaseBackup()函数内部,会首先传送WAL日志(如果指定了-x选项的话).随后依次遍历所有 ...

  9. 64位的notepad++没有插件管理

    下载的64位的notepad++没有插件管理:需要自己下载这个插件: - plugin manager的下载地址为:https://github.com/bruderstein/nppPluginMa ...

  10. artDialog不能拖拽的问题

    需要引用下面这个文件: https://github.com/aui/artDialog/edit/master/dist/dialog-plus.js