我正在使用某些与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包装器)中仅为单元测试添加一定数量的抽象,虽然感觉不对,但最终是唯一的选择。