web-dev-qa-db-ja.com

ASP.NET MVC 1のHttpContextBaseからHttpContextオブジェクトを取得するにはどうすればよいですか?

私はいくつかのWebForms/MVCに依存しないツールを使用しており、HttpContextオブジェクトへの参照を指定してHttpContextBaseのインスタンスを取得する必要があります。使用できませんHttpContext.Currentこれは非同期で動作するためにも必要だからです(HttpContext.Currentは、非同期リクエスト中にnullを返します)。私はHttpContextWrapperを知っていますが、間違った方向に進みます。

148
Daniel Schaffer

最も簡単な方法は、アプリケーション ApplicationInstance を取得し、その Context プロパティを使用することです。

// httpContextBase is of type HttpContextBase
HttpContext context = httpContextBase.ApplicationInstance.Context;

Ishmael Smyrnow に感謝します)

元の回答:

特に、渡されたHttpContextBaseインスタンスのタイプが HttpContextWrapper である場合、実行時にできます。次の例は、これを行う方法を示しています。コンテキストをFooとして受け入れるHttpContextBaseと呼ばれるメソッドがあるが、サードパーティアセンブリ(変更する幸運がないかもしれない)のメソッドを呼び出す必要があると仮定します。 HttpContextとして入力されるコンテキスト。

void Foo(HttpContextBase context) 
{
    var app = (HttpApplication) context.GetService(typeof(HttpApplication));
    ThirdParty.Bar.Baz(app.Context);
}

// Somewhere in Assembly and namespace ThirdParty,
// in a class called Bar, there is Baz expecting HttpContext:

static void Baz(HttpContext context) { /* ... */ }

HttpContextBaseには、 GetService のサポートの結果として IServiceProvider というメソッドがあります。 GetServiceHttpContextWrapperオーバーライドは、ラップされたGetServiceインスタンスのHttpContext実装に委任します。 GetServiceHttpContext実装により、HttpApplicationHttpRequestHttpResponseなどの通常の容疑者を照会できます。 HttpApplicationContext と呼ばれるプロパティがあり、HttpContextのインスタンスを返すことがあります。したがって、ラップされたHttpContextインスタンスを取得するには、HttpContextBaseHttpApplicationGetService経由で要求し、続いて返されたContextインスタンスのHttpApplicationプロパティを読み取ります。 。

HttpContextBaseとは異なり、GetServiceHttpContextのパブリックメンバーとして表示されませんが、それはHttpContextIServiceProvider.GetService明示的にHttpContextBaseはそうではありません。

Fooは、テスト中に基礎となるHttpContextをアンラップできることに依存しており、そもそも偽造/スタブが不可能に近いため、もはやテスト可能ではないことに留意してください。ただし、この答えのポイントは、「HttpContextBaseからHttpContextオブジェクトを取得する方法は?」、literallyという質問に対処することです。図に示した手法は、必ずしも変更する余裕がないコンポーネントの間に挟まれているような状況で役立ちます。

237
Atif Aziz

あなたはできる、

var abstractContext = new System.Web.HttpContextWrapper(System.Web.HttpContext.Current);
30
Marc Chouteau

できません。

HttpContextBaseの目的は、具体的なHttpContextクラスへの依存関係を抽象化することです。 may具象HttpContexthttpContextWrapperの場合などが含まれていますが、他の実装ではまったく関係ない場合がありますHttpContext

HttpContextBaseで具体的なHttpContextをいつでもラップできるので、最適なオプションはHttpContextWrapperを取得できるカスタム抽象ファクトリを定義することです。

14
Mark Seemann