我正在使用一些与 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) { /* ... */ }
HttpContextBaseGetService有一个由于支持而被调用的方法IServiceProvider。对包装实例实现的委托的GetService覆盖。的实现允许您查询常见的嫌疑人,如、等。碰巧有一个名为Context的属性并返回. 因此,通过请求via然后读取返回实例的属性来获取包装的实例。HttpContextWrapperGetServiceHttpContextGetServiceHttpContextHttpApplicationHttpRequestHttpResponseHttpApplicationHttpContextHttpContextHttpContextBaseHttpApplicationGetServiceContextHttpApplication
与HttpContextBase,不同,GetService它不会作为公共成员出现,HttpContext但那是因为明确地HttpContext实现了,而没有。IServiceProvider.GetServiceHttpContextBase
请记住,Foo它不再是可测试的,因为它依赖于能够HttpContext在测试期间解开底层,并且首先几乎不可能伪造/存根。然而,这个答案的重点是解决这个问题,“我如何从 HttpContextBase 获取 HttpContext 对象?”,字面意思。在您发现自己被夹在您不一定有权修改的组件之间的情况下,图示的技术很有用。
你可以,
var abstractContext = new System.Web.HttpContextWrapper(System.Web.HttpContext.Current);
你不能。
的全部目的是抽象出对具体类HttpContextBase的依赖。HttpContext虽然它可能包含一个具体的HttpContext (例如 的情况httpContextWrapper),但其他实现可能与HttpContext.
您最好的选择是定义一个可以HttpContextBase为您获取 a 的自定义抽象工厂,因为您始终可以将混凝土包装HttpContext在HttpContextWrapper.