我正在使用一些WebForms / MVC无关的工具,我需要获得HttpContext
的实例,并提供对HttpContextBase
对象的引用。我不能使用HttpContext.Current
因为我需要异步工作(HttpContext.Current
在异步请求期间返回null
)。我知道HttpContextWrapper
,但走错路。
答案 0 :(得分:233)
最简单的方法是获取应用程序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) { /* ... */ }
由于支持GetService
, HttpContextBase
有一个名为IServiceProvider
的方法。 GetService
的{{1}}覆盖委托给包装HttpContextWrapper
实例的GetService
实现。 HttpContext
的{{1}}实施允许您查询常见的嫌疑人,例如GetService
,HttpContext
,HttpApplication
等。恰好HttpRequest
有一个名为Context的属性并返回HttpResponse
的实例。因此,通过HttpApplication
通过HttpContext
询问HttpContext
,然后阅读返回的HttpContextBase
实例的HttpApplication
属性,可以获取已包装的GetService
实例
与Context
不同,HttpApplication
不会显示为HttpContextBase
的公开成员,但这是因为GetService
实现HttpContext
明确而HttpContext
没有。
请记住,IServiceProvider.GetService
不再可测试,因为它依赖于能够在测试期间展开底层HttpContextBase
,并且几乎不可能伪造/存根。然而,这个答案的要点是解决这个问题,“如何从HttpContextBase获取HttpContext对象?”,字面意思。图解技术在您发现自己夹在组件之间的情况下非常有用,这些组件不一定可以修改。
答案 1 :(得分:30)
你可以,
var abstractContext = new System.Web.HttpContextWrapper(System.Web.HttpContext.Current);
答案 2 :(得分:14)
你不能。
HttpContextBase
的全部目的是抽象出对具体HttpContext
类的依赖。虽然可能包含具体的HttpContext
(例如httpContextWrapper
的情况),但其他实现可能与{{完全无关1}}。
您最好的选择是定义一个可以为您获取HttpContext
的自定义抽象工厂,因为您始终可以在HttpContextBase
中包含具体的HttpContext
。