159

我正在使用一些与 WebForms/MVC 无关的工具,我需要获取HttpContext给定HttpContextBase对象引用的实例。我不能使用HttpContext.Current,因为我也需要它异步工作(在异步请求期间HttpContext.Current返回)。null我知道HttpContextWrapper,但走错路了。

4

3 回答 3

254

最简单的方法是获取应用程序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 对象?”,字面意思。在您发现自己被夹在您不一定有权修改的组件之间的情况下,图示的技术很有用。

于 2010-12-31T02:34:36.053 回答
33

你可以,

var abstractContext = new System.Web.HttpContextWrapper(System.Web.HttpContext.Current);
于 2010-08-12T21:07:10.017 回答
14

你不能。

的全部目的是抽象出对具体类HttpContextBase的依赖。HttpContext虽然它可能包含一个具体的HttpContext (例如 的情况httpContextWrapper,但其他实现可能与HttpContext.

您最好的选择是定义一个可以HttpContextBase为您获取 a 的自定义抽象工厂,因为您始终可以将混凝土包装HttpContextHttpContextWrapper.

于 2010-01-02T17:30:12.477 回答