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中的實現。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM