我正在使用一些与 WebForms/MVC 无关的工具,我需要获取HttpContext
给定HttpContextBase
对象引用的实例。我不能使用HttpContext.Current
,因为我也需要它异步工作(在异步请求期间HttpContext.Current
返回)。null
我知道HttpContextWrapper
,但走错路了。
3 回答
最简单的方法是获取应用程序ApplicationInstance
, 并使用其Context
属性:
// httpContextBase is of type HttpContextBase
HttpContext context = httpContextBase.ApplicationInstance.Context;
(感谢Ishmael Smyrnow在评论中指出这一点)
原答案:
您可以,特别是如果您收到的HttpContextBase
实例是HttpContextWrapper
运行时的类型。以下示例说明了如何执行此操作。它假设您有一个名为的方法,该方法Foo
接受 context asHttpContextBase
但随后需要调用第三方程序集中的方法(您可能没有好运修改),该方法期望将上下文键入为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
覆盖。的实现允许您查询常见的嫌疑人,如、等。碰巧有一个名为Context的属性并返回. 因此,通过请求via然后读取返回实例的属性来获取包装的实例。HttpContextWrapper
GetService
HttpContext
GetService
HttpContext
HttpApplication
HttpRequest
HttpResponse
HttpApplication
HttpContext
HttpContext
HttpContextBase
HttpApplication
GetService
Context
HttpApplication
与HttpContextBase
,不同,GetService
它不会作为公共成员出现,HttpContext
但那是因为明确地HttpContext
实现了,而没有。IServiceProvider.GetService
HttpContextBase
请记住,Foo
它不再是可测试的,因为它依赖于能够HttpContext
在测试期间解开底层,并且首先几乎不可能伪造/存根。然而,这个答案的重点是解决这个问题,“我如何从 HttpContextBase 获取 HttpContext 对象?”,字面意思。在您发现自己被夹在您不一定有权修改的组件之间的情况下,图示的技术很有用。
你可以,
var abstractContext = new System.Web.HttpContextWrapper(System.Web.HttpContext.Current);
你不能。
的全部目的是抽象出对具体类HttpContextBase
的依赖。HttpContext
虽然它可能包含一个具体的HttpContext
(例如 的情况httpContextWrapper
),但其他实现可能与HttpContext
.
您最好的选择是定义一个可以HttpContextBase
为您获取 a 的自定义抽象工厂,因为您始终可以将混凝土包装HttpContext
在HttpContextWrapper
.