zoukankan      html  css  js  c++  java
  • [转]ASP.NET MVC中的两个Action之间值的传递--TempData

    本文转自: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中的实现。

     
     
    分类: ASP.Net_MVC
  • 相关阅读:
    [转]Centos 查看端口占用情况和开启端口命令
    [转]简单美观的文字标签云组件
    [转]scp、sftp命令使用
    清华大学《C++语言程序设计基础》线上课程笔记03---数据的共享和保护&数组
    清华大学《C++语言程序设计基础》线上课程笔记02---类与对象
    清华大学《C++语言程序设计基础》线上课程笔记01---基础概念与一些注意事项
    新的玩具:Windows上的awesome
    环境变量ANDROID_SDK_HOME的作用
    Android Dalvik和JVM的区别
    是否使用TDD(测试驱动开发)进行UI开发
  • 原文地址:https://www.cnblogs.com/freeliver54/p/6405782.html
Copyright © 2011-2022 走看看