首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> ASP.NET 基礎 >> 關於ASP.NET

ASP.NET MVC 1.0 深度剖析 (2):TempData Load/Save 與 ExecuteCore 執行流程

     編輯:關於ASP.NET

`Controller.ExecuteCore()` 是 Action 執行的核心入口,僅三行程式碼卻包含 TempData 載入、Action 執行、TempData 儲存完整週期。本文詳細剖析 `TempDataDictionary`、`SessionStateTempDataProvider` 運作細節。

ExecuteCore 核心程式碼

protected override void ExecuteCore()
{
    TempData.Load(ControllerContext, TempDataProvider);
    try
    {
        string actionName = RouteData.GetRequiredString("action");
        if (!ActionInvoker.InvokeAction(ControllerContext, actionName))
            HandleUnknownAction(actionName);
    }
    finally
    {
        TempData.Save(ControllerContext, TempDataProvider);
    }
}

TempData.Load 詳細流程

public void Load(ControllerContext controllerContext, ITempDataProvider tempDataProvider)
{
    IDictionary<string, object> providerDictionary = tempDataProvider.LoadTempData(controllerContext);
    _data = (providerDictionary != null)
        ? new Dictionary<string, object>(providerDictionary, StringComparer.OrdinalIgnoreCase)
        : new Dictionary<string, object>(StringComparer.OrdinalIgnoreCase);
    _initialKeys = new HashSet<string>(_data.Keys);
    _modifiedKeys.Clear();
}
  • `TempDataProvider` 預設為 `SessionStateTempDataProvider`,從 `HttpContext.Session["__ControllerTempData"]` 讀取字典。
  • 載入後建立 `_initialKeys` 記錄初始鍵集,`_modifiedKeys` 追蹤本次請求新增/修改的鍵。

TempData.Save 詳細流程

public void Save(ControllerContext controllerContext, ITempDataProvider tempDataProvider)
{
    var dictionary = new Dictionary<string, object>(_data, StringComparer.OrdinalIgnoreCase);
    // 移除標記為刪除的鍵 (Keep() 未呼叫的初始鍵)
    foreach (string key in _initialKeys)
        if (!_modifiedKeys.Contains(key)) dictionary.Remove(key);
    tempDataProvider.SaveTempData(controllerContext, dictionary);
}
  • 僅保存 `_modifiedKeys` 包含的鍵(新增/修改/呼叫 `Keep()` 的初始鍵)。
  • 未標記保留的初始鍵自動移除,實現「一次性」語意:跨請求讀取後自動失效。

SessionStateTempDataProvider 實作

public IDictionary<string, object> LoadTempData(ControllerContext controllerContext)
{
    var session = controllerContext.HttpContext.Session;
    if (session != null)
    {
        var data = session["__ControllerTempData"] as IDictionary<string, object>;
        session.Remove("__ControllerTempData"); // 讀取即移除,確保一次性
        return data;
    }
    return null;
}

public void SaveTempData(ControllerContext controllerContext, IDictionary<string, object> values)
{
    if (values != null && values.Count > 0)
        controllerContext.HttpContext.Session["__ControllerTempData"] = values;
}

關鍵設計亮點

  1. 讀取即刪除 Session:`LoadTempData` 中 `session.Remove()` 確保 TempData 僅在下一個請求可用,防止重複讀取。
  2. 字典比對機制:`_initialKeys` vs `_modifiedKeys` 精確控制保留/移除。
  3. Provider 抽象化:`ITempDataProvider` 可替換為 Cookie、Cache、分散式 Session 等實作。

常見誤區與最佳實踐

  • ❌ `TempData["msg"] = "成功";` 連續兩個 Action 讀取 → 第二次為 null。
    ✅ 跨多請求需呼叫 `TempData.Keep("msg")` 或 `TempData.Keep()`。
  • Redirect 後顯示訊息:`TempData["msg"] = "..."; return RedirectToAction("Index");` → View 中 `@TempData["msg"]` 正確顯示一次。
  • 大量資料勿存 TempData (Session 大小限制),改用快取或資料庫。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved