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


155

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

回答:


250

最も簡単な方法は、アプリケーションを取得し、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) { /* ... */ }

HttpContextBaseGetServiceサポートの結果として呼び出されるメソッドがありIServiceProviderます。ラップされたインスタンスの実装へGetServiceHttpContextWrapperデリゲートのオーバーライド。実装は、のような通常の容疑者のクエリにあなたを可能にする、、のように。たまたま、Contextというプロパティがあり、のインスタンスを返す場合があります。そのため、viaを要求し、続いて返されたインスタンスのプロパティを読み取ることで、ラップされたインスタンスを取得します。GetServiceHttpContextGetServiceHttpContextHttpApplicationHttpRequestHttpResponseHttpApplicationHttpContextHttpContextHttpContextBaseHttpApplicationGetServiceContextHttpApplication

とは異なりHttpContextBaseGetServiceはのパブリックメンバーとしては表示されませんHttpContextが、は明示的にをHttpContext実装しているのに、IServiceProvider.GetService明示的にHttpContextBaseは実装していないためです。

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


3
非常に興味深い答えです。自分でMVCを使用して、HttpContextをエラーフィルターからELMAHに渡し、ログに記録しました。
Chris Marisic

1
いい答えです、少し掘り下げましたか?:)
longhairedsi

すばらしい答えです!私は特にElmahからMVCコントローラーgithub.com/alexanderbeletsky/elmah.mvc.controller/blob/master/…
Alexander Beletsky 2011

36
HttpContextBaseを使用すると、呼び出すことができませんでしたcontext.ApplicationInstance.Contextか?
Ishmael Smyrnow、2011年

@IshmaelSmyrnowくそー、私がHttp*Baseによって返されたすべてのバリエーションの中でそれを逃したことはありませんHttpContextBase。:P答えを更新します。
Atif Aziz

32

あなたはできる、

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

16
-1これは間違った方法です。これにより、コンテキストがあるときにベースが得られます。逆ではありません。
Chris Marisic

14

できません。

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

HttpContextBase常に具象をHttpContextでラップできるため、最適なオプションは、を取得できるカスタムの抽象ファクトリを定義することですHttpContextWrapper


13
ちなみにこれはひどく行われました-ユニットテストのセットアップが必要だと理解し、抽象化のレイヤーも理解しています-しかし、HttpContextを期待する既存のASP.NETクラスを使用したい場合は、WTHを実行する必要がありますか?(msdn.microsoft.com/en-us/library/…など
marq

IHttpHandler実装をテストするには、ユニットテストのために(応答ラッパー)に抽象化の敷居数を配置する必要がありますが、これは正しくないように思われますが、唯一の選択肢となります。
Chris S
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.