36

シングルトンパターンを使用する独自の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.NETMVCとASP.NETWebフォームの間で共有されていません。この結果、HttpContext.Itemsコレクションを使用してデータのビットを格納および取得することはできません。

これは、コントローラーにリダイレクトすると、HttpHandlerがSystem.Web.Mvc.MvcHandlerになるためです。これは、HttpContextWrapperを使用して作成され、独自のHttpContext.Currentの定義があります。残念ながら、このハンドシェイク中は、HttpContext.Itemsなどは転送されません。

つまり、HttpContextの型は、見た目も音もほとんど同じですが、同じではなく、この方法でデータを渡すことはできません。

今、私はこれをテストしようとしました、そして私が知る限り、RedirectToActionを使用して別のコントローラーにリダイレクトする場合、HttpContext.Itemsは残ります。これをテストするために、デフォルトのASP.NETMVCプロジェクトを使用しています。私がやったことは、このメソッドを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に設定されている正しい「HelloWorld」文字列を書き込みます。

そのため、「HttpContext.Itemsのようなものは転送されない」と書かれている場合、本の意味がわからないように見えます。または、このようなものは転送され、HttpContext.Itemsを使用しても問題ありません。

HttpContext.Itemsを避けることをお勧めする場合、リクエストごとにオブジェクトをリクエスト全体に保存する別の方法はありますか?

4

3 に答える 3

41

あなたの質問はいくつかのことを尋ねていますが、私はアイテム#1があなたが探している答えだと思います。

  1. Context.Itemsリクエストごとにキャッシュに使用しても問題ありませんか?はい。処理中、リクエストごと、Webファーム内のマシンごとが基準である場合、Context.Itemsはそれを提供します。

  2. テストするのはContext.Items難しいですか?テスト容易性に関しては、私はContext.Itemsある種のインターフェースの後ろに隠れます。Context.Itemsこのようにして、直接参照しなくても単体テスト機能を利用できます。そうでなければ、あなたは何についてテストする必要がありますContext.Itemsか?フレームワークが値を保存および取得することは?コードを知らないようにしておくSystem.Webと、幸せなキャンピングカーになります。

  3. Context.Items生き残るのだろRedirectToActionうか?いいえ。テストは無効です。すべてのWebリクエストに「Hello、world」が設定されており、テストは2つのWebリクエストにまたがっています。1つ目は、インデックスアクションが呼び出されたときです。2つ目は、RedirectToActionアクションが呼び出されたときです(HTTP 302です)。失敗させるには、[インデックス]アクションで新しい値を設定し、[バージョン情報]アクションでその値が保持されているかどうかを確認します。

于 2009-07-16T06:14:47.553 に答える
4

TempDataディクショナリを使用します。これは、主にアクションリダイレクト間でオブジェクトを格納するためのものです。

public ActionResult Index()
{
    TempData.Add("Test", "Hello world");
    return RedirectToAction("About");
}

public ActionResult About()
{
    ViewData["Test"] = TempData["Test"];
    return View();
}

次に、ビューで値を取得します。

<%=ViewData["Test"] %>
于 2009-07-15T23:00:50.980 に答える
1

私はテストを行いましたが、TempDataは実際、セッション状態を無効にして爆発します。私の唯一のアドバイスは、オブジェクト自体を一時データに格納するのではなく、提案されているように単純な型付きフィールドを格納することです。オブジェクトツリーをシリアル化していないので、アウトプロセスで実行されるパフォーマンスへの影響はそれほど大きくないはずです。

于 2009-07-16T01:51:25.517 に答える