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