我正在使用某些与WebForms / MVC无关的工具,并且需要获取HttpContext
给定HttpContextBase
对象引用的实例。我无法使用,HttpContext.Current
因为我还需要它也能异步工作(在异步请求期间HttpContext.Current
返回null
)。我知道HttpContextWrapper
,但是走错了路。
我正在使用某些与WebForms / MVC无关的工具,并且需要获取HttpContext
给定HttpContextBase
对象引用的实例。我无法使用,HttpContext.Current
因为我还需要它也能异步工作(在异步请求期间HttpContext.Current
返回null
)。我知道HttpContextWrapper
,但是走错了路。
Answers:
最简单的方法是获取应用程序ApplicationInstance
并使用其Context
属性:
// httpContextBase is of type HttpContextBase
HttpContext context = httpContextBase.ApplicationInstance.Context;
(感谢Ishmael Smyrnow在评论中指出了这一点)
您可以这样做,尤其是如果HttpContextBase
您处理的实例HttpContextWrapper
在运行时是类型的。以下示例说明了如何执行此操作。假设您有一个名为的方法Foo
,它接受context作为,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
。在GetService
的覆盖HttpContextWrapper
委托给GetService
包裹的执行HttpContext
情况。该GetService
实施HttpContext
允许您查询秋后算账一样HttpApplication
,HttpRequest
,HttpResponse
等等。碰巧HttpApplication
有一个名为Context的属性,该属性返回的实例HttpContext
。因此,人们在包裹得HttpContext
例如通过询问HttpContextBase
对HttpApplication
通过GetService
随后通过读取Context
返回的财产HttpApplication
情况。
与不同HttpContextBase
,GetService
不会显示为的公共成员,HttpContext
但这是因为HttpContext
实现IServiceProvider.GetService
显式而HttpContextBase
没有。
请记住,Foo
它不再是可测试的,因为它依赖于能够HttpContext
在测试过程中解开底层的内容,并且几乎不可能首先伪造/存根。这个答案的要点,但是,是要解决问题,“我如何从一个HttpContextBase HttpContext对象?”,从字面上。在您发现自己被夹在组件之间的情况下,图示的技术很有用。
context.ApplicationInstance.Context
吗?
Http*Base
返回的变体中错过的那个HttpContextBase
。:P我将更新答案。
你不能
的全部目的HttpContextBase
是抽象出对具体HttpContext
类的依赖。尽管它可能包含具体内容HttpContext
(例如的情况httpContextWrapper
),但其他实现可能与绝对无关HttpContext
。
最好的选择是定义一个自定义的Abstract Factory,它可以HttpContextBase
为您提供,因为您始终可以将混凝土包裹HttpContext
在中HttpContextWrapper
。
IHttpHandler
实现,您最终不得不在(Response包装器)中仅为单元测试添加一定数量的抽象,虽然感觉不对,但最终是唯一的选择。