ASP.NET MVC を使用した HttpContext.Items
-
16-09-2019 - |
質問
シングルトン パターンを使用する独自の ApplicationContext クラスを実装しています。リクエストのすべての部分でアクセスできるため、そのインスタンスを HttpContext.Items に保存したいと考えています。ASP.NET MVC での HttpContext の使用について読んでいましたが、大きな問題の 1 つは、テストが複雑になることです。HttpContext.Items のテスト可能性について調査しようとしましたが、見つかるのは Session に関するものだけです。私が見つけた唯一のことの 1 つは、Wrox に関する Professional ASP.NET 3.5 MVC ブックのサンプル章からのものです (pdfリンクはこちら)。15ページにはこう書かれています。
使用できないもの:HttpContext.Items
このセクションの上で、私たちはあなたに嘘をついていたことを白状しました。HttpContext は、ASP.NET MVC と ASP.NET Web フォームの間で共有されません。この結果、HttpContext.Items コレクションを使用してデータのビットを保存および取得することができなくなります。
その理由は、コントローラーにリダイレクトすると、HttpHandler が System.Web.Mvc.MvcHandler になり、HttpContextWrapper を使用して作成され、HttpContext.Current の独自の定義を持つためです。残念ながら、このハンドシェイク中に HttpContext.Items などは転送されません。
これを要約すると、HttpContext 型は、見た目もサウンドもほとんど同じであるにもかかわらず、同じではなく、この方法ではデータを渡すことができないということになります。
さて、これをテストしてみましたが、私の知る限り、RedirectToAction を使用して別のコントローラーにリダイレクトしても、HttpContext.Items は残ります。これをテストするためにデフォルトの ASP.NET MVC プロジェクトを使用しています。私がやったことは、このメソッドを Global.asax.cs に追加することです。
protected void Application_BeginRequest()
{
Context.Items["Test"] = "Hello World";
}
そして、HomeController.cs では、Index メソッドを次のように変更しました。
public ActionResult Index()
{
return RedirectToAction("About");
}
そして、About メソッドを次のように変更しました。
public ActionResult About()
{
Response.Write(Convert.ToString(HttpContext.Items["Test"]));
return View();
}
アプリケーションを実行すると、ページは /Home/About および Response に適切にリダイレクトされ、global.asax.cs に設定された正しい「Hello World」文字列が書き込まれます。
ですから、「httpcontext.itemsが転送されない」と言うとき、本が何を意味しているかを理解していないか、このものを転送しているように思えます。
HttpContext.Items を避けるよう勧める場合、リクエストごとにリクエスト全体にわたってオブジェクトを保存する別の方法はありますか?
解決
あなたの質問はいくつかのことを尋ねていますが、項目#1があなたが探している答えだと思います。
使っても大丈夫ですか?
Context.Items
リクエストごとにキャッシュするには?はい。処理中、リクエストごと、Web ファーム内のマシンごとが基準である場合、Context.Items がそれを提供します。は
Context.Items
テストするのは難しいですか?テスト容易性に関しては、私は隠しますContext.Items
ある種のインターフェイスの背後にあります。このようにして、参照することなく単体テスト機能を取得できます。Context.Items
直接。それ以外の場合、何をテストする必要がありますかContext.Items
?フレームワークが値を保存したり取得したりするのでしょうか?コードを無視してくださいSystem.Web
そしてあなたも幸せなキャンパーになれるでしょう。意思
Context.Items
生き残るRedirectToAction
?いいえ。あなたのテストは無効です。すべての Web リクエストに「Hello, world」を設定し、テストは 2 つの Web リクエストにまたがります。1 つ目は、Index アクションが呼び出されるときです。2つ目は、そのときですRedirectToAction
アクションが呼び出されます (HTTP 302 です)。失敗させるには、Index アクションに新しい値を設定し、それが About アクションに保持されているかどうかを確認します。
他のヒント
TempData ディクショナリを使用します。これは主に、アクション リダイレクト間にオブジェクトを保存するために使用されます。
public ActionResult Index()
{
TempData.Add("Test", "Hello world");
return RedirectToAction("About");
}
public ActionResult About()
{
ViewData["Test"] = TempData["Test"];
return View();
}
次に、ビュー内の値を取得します。
<%=ViewData["Test"] %>
テストを行ったところ、セッション状態が無効になっていると確かに TempData が爆発しました。私の唯一のアドバイスは、オブジェクト自体を一時データに保存せず、提案されているように単純な型付きフィールドを保存することです。オブジェクト ツリーをシリアル化していないため、アウトプロセスで実行してもパフォーマンスに大きな影響はありません。