ASPを深く分析する.NET Mvc 1.0 – 2. Controller.Execute(Request)-TempDataDictionaryのLoadとSave操作
8494 ワード
Controllerは最終的にControllerBaseクラスのExecute(RequestContext)メソッドを呼び出すことでアクションの作成と実行を完了します.コードは次のとおりです.
コードは2つのステップに分かれています. Initialize(requestContext):ControllerContextクラスのインスタンスを作成します. ExecuteCore():TempDataをロードし、Actionを作成および実行し、Actionから返されるActionResultを処理し、TempDataデータを保存します.
ExecuteCore()のコードは次のとおりです.
コードは、次の3つのセクションに分かれています. TempData.Load(ControllerContext,TempDataProvider):HttpContextBase.SessionでのTempDataデータのロード ActionInvoker.InvokeAction(ControllerContext,actionName):Actionを作成、実行し、Actionが返すActionResult を処理します. TempData.Save(ControllerContext,TempDataProvider):TempData を保存する
第1,第3部はいずれもTempDataに対する操作であり,以下の2つのステップについて詳細に説明する.
1. TempData.Load(ControllerContext, TempDataProvider)
TempDataProvider:SessionStateTempDataProviderです.ITempDataProviderインタフェースを継承したSession補助クラスです.
TempDataProvider.Loadのソース:
ここでは、TempDataをロードするすべてのプロセスです. SessionStateTempDataProviderのLoadTempData(...)メソッドを呼び出し、IDictionaryオブジェクト に戻る.初期化_Dataオブジェクト、providerDictionaryがnullでない場合、providerDictionaryのデータを_に格納します.dataオブジェクトでは、実はこの_DataはTempDataがデータを保存するためのコンテナであり、 初期化_initialKeysオブジェクトと_DataのすべてのKey値が挿入され、ロードされたKey値をキャッシュするために使用されます.TempDataに新しいデータを挿入すると、initialKeysオブジェクトのデータにはタスクの変更はありません クリア_modifiedKeysの値は、TempDataの新しいKey値を保存するために使用され、新しいキー値ペアがTempDataに挿入されると、このkey値は_に保存されます.modifiedKeysオブジェクトの さらにtempDataProvider.LoadTempData(controllerContext)メソッドは、S e ssionStateTempDataProviderクラスのLoadTempData(...)メソッドです.
SessionStateTempData Providerクラスには、Sessionに保存されているTempDataオブジェクトのKeyとして使用する定数が定義されています.
LoadTempData(…)メソッドでは、まず、keyに対応するDictionaryオブジェクトをSessionで検索し、Sessionにこのオブジェクトが存在する場合は、Sessionのこのキー値ペアをクリアして見つかったDictionaryオブジェクトを返します.Noは、新しいDictionaryオブジェクトを作成して返します.
ここのポイントはhttpContextです.Session.Remove(TempDataSessionStateKey)メソッドは、同じTempDataが1回しか伝達されないというTempDataの特徴でもあります.SessionでTempDataを見つけたらすぐにそれをSessionから消去し、次にLoadTempData()メソッドを実行すると、同じTempDataは二度と見つかりません.
再度説明:1つのキー値ペアをTempDataに入れると、同じControllerの異なるActionでも異なるControllerの異なるActionでもこのTempDataを受信できますが、一度だけ、プログラムが再びサービス側にコミットされると、同じ値を取得できないTempDataオブジェクトになります.これは、Sessionで消去されているためです.
2. TempData.Save(ControllerContext, TempDataProvider)
これはコントローラ全体です.Execute(...)ライフサイクルの最後の操作は、新しいTempDataをHttpContext.に保存することです.Base.セッション中です.セーブメソッドの具体的なコード:
上に述べたようにinitialKeysと_modifiedKeysの重要性、それらの役割はここで体現されます. _InitialKeys:Action実行前のTempDataのすべてのKey値を保存します.action実行中に新しいキー値ペアがTempDataに挿入された場合、_InitialKeysオブジェクトの値は影響しません. _modifiedKeys:Action実行中に新しいキー値ペアがTempDataに挿入された場合、この新しいキーは_に挿入されます.modifiedKeysオブジェクト.
セーブメソッドではまず判断_modifiedKeysオブジェクトの要素の数、新しいキー値ペアがTempDataに挿入されているかどうか、foreachと次のif文はTempDataから不要なキー値ペアデータを削除し、最後にtempData Providerを呼び出す.SaveTempData(controllerContext,_data)メソッドは、TempDataをHttpContextBaseに保存する.セッション中です.
注意:最後に定義したTempDataのデータは、TempDataのロード中に_に格納されます.Dataでは、ここでforeach,if文は、渡す必要のないキー値ペアを削除し、TempDataに今回のAction実行中に生成されたキー値ペアデータのみが保持されていることを確認します.
protected virtual void Execute(RequestContext requestContext) {
if (requestContext == null) {
throw new ArgumentNullException("requestContext");
}
Initialize(requestContext);
ExecuteCore();
}
コードは2つのステップに分かれています.
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);
}
}
コードは、次の3つのセクションに分かれています.
第1,第3部はいずれもTempDataに対する操作であり,以下の2つのステップについて詳細に説明する.
1. TempData.Load(ControllerContext, TempDataProvider)
TempDataProvider:SessionStateTempDataProviderです.ITempDataProviderインタフェースを継承したSession補助クラスです.
TempDataProvider.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();
}
ここでは、TempDataをロードするすべてのプロセスです.
public virtual IDictionary<string, object> LoadTempData(ControllerContext controllerContext) {
HttpContextBase httpContext = controllerContext.HttpContext;
if (httpContext.Session == null) {
throw new InvalidOperationException(MvcResources.SessionStateTempDataProvider_SessionStateDisabled);
}
Dictionary<string, object> tempDataDictionary = httpContext.Session[TempDataSessionStateKey] as Dictionary<string, object>;
if (tempDataDictionary != null) {
// If we got it from Session, remove it so that no other request gets it
httpContext.Session.Remove(TempDataSessionStateKey);
return tempDataDictionary;
}
else {
return new Dictionary<string, object>(StringComparer.OrdinalIgnoreCase);
}
}
SessionStateTempData Providerクラスには、Sessionに保存されているTempDataオブジェクトのKeyとして使用する定数が定義されています.
internal const string TempDataSessionStateKey = "__ControllerTempData";
LoadTempData(…)メソッドでは、まず、keyに対応するDictionary
ここのポイントはhttpContextです.Session.Remove(TempDataSessionStateKey)メソッドは、同じTempDataが1回しか伝達されないというTempDataの特徴でもあります.SessionでTempDataを見つけたらすぐにそれをSessionから消去し、次にLoadTempData()メソッドを実行すると、同じTempDataは二度と見つかりません.
再度説明:1つのキー値ペアをTempDataに入れると、同じControllerの異なるActionでも異なるControllerの異なるActionでもこのTempDataを受信できますが、一度だけ、プログラムが再びサービス側にコミットされると、同じ値を取得できないTempDataオブジェクトになります.これは、Sessionで消去されているためです.
2. TempData.Save(ControllerContext, TempDataProvider)
これはコントローラ全体です.Execute(...)ライフサイクルの最後の操作は、新しいTempDataをHttpContext.に保存することです.Base.セッション中です.セーブメソッドの具体的なコード:
public void Save(ControllerContext controllerContext, ITempDataProvider tempDataProvider) {
if (_modifiedKeys.Count > 0) {
// Apply change tracking.
foreach (string x in _initialKeys) {
if (!_modifiedKeys.Contains(x)) {
_data.Remove(x);
}
}
// Store the dictionary
tempDataProvider.SaveTempData(controllerContext, _data);
}
}
上に述べたようにinitialKeysと_modifiedKeysの重要性、それらの役割はここで体現されます.
セーブメソッドではまず判断_modifiedKeysオブジェクトの要素の数、新しいキー値ペアがTempDataに挿入されているかどうか、foreachと次のif文はTempDataから不要なキー値ペアデータを削除し、最後にtempData Providerを呼び出す.SaveTempData(controllerContext,_data)メソッドは、TempDataをHttpContextBaseに保存する.セッション中です.
注意:最後に定義したTempDataのデータは、TempDataのロード中に_に格納されます.Dataでは、ここでforeach,if文は、渡す必要のないキー値ペアを削除し、TempDataに今回のAction実行中に生成されたキー値ペアデータのみが保持されていることを確認します.