如何从ASP.NET MVC 1中的HttpContextBase获取HttpContext对象?
我正在使用一些WebForms / MVC不可知论的工具,我需要得到一个HttpContext
的实例给定一个HttpContextBase
对象的引用。 我不能使用HttpContext.Current
因为我需要这个asynchronous工作( HttpContext.Current
asynchronous请求期间返回null
)。 我知道HttpContextWrapper
,但错误的方式。
最简单的方法是获取应用程序ApplicationInstance
并使用其Context
属性:
// httpContextBase is of type HttpContextBase HttpContext context = httpContextBase.ApplicationInstance.Context;
(感谢Ishmael Smyrnow在评论中提到这一点)
原始答案:
你可以,特别是如果你已经交给的HttpContextBase
实例在运行时是HttpContextWrapper
types的话。 以下示例说明如何执行此操作。 它假设你有一个名为Foo
的方法,接受上下文作为HttpContextBase
但是需要调用第三方程序集中的方法(你可能没有修改的好处),这个方法需要将上下文types化为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) { /* ... */ }
由于支持IServiceProvider
HttpContextBase
有一个名为GetService
的方法。 HttpContextWrapper
的GetService
覆盖委托给包装的HttpContext
实例的GetService
实现。 HttpContext
的GetService
实现允许您查询常见的嫌疑人,如HttpApplication
, HttpRequest
, HttpResponse
等等。 恰巧, HttpApplication
有一个名为Context的属性,它返回一个HttpContext
的实例。 所以通过GetService
获取HttpContextBase
的HttpApplication
,然后读取返回的HttpApplication
实例的Context
属性,就可以得到包装的HttpContext
实例。
与HttpContextBase
不同, GetService
不会作为HttpContext
的公共成员出现,但是这是因为HttpContext
实现了IServiceProvider.GetService
而HttpContextBase
则没有。
请记住, Foo
不再是可testing的,因为它依赖于能够在testing过程中展开底层的HttpContext
,并且在第一个位置旁边不可能伪造/存根。 但是,这个答案的重点在于解决“从HttpContextBase获取HttpContext对象的方法”这个问题。 所示的技术在您发现自己夹在不一定有修改奢侈品的组件之间的情况下非常有用。
您可以,
var abstractContext = new System.Web.HttpContextWrapper(System.Web.HttpContext.Current);
你不能。
HttpContextBase
的全部目的是抽象出具体的HttpContext
类的依赖关系。 虽然它可能包含一个具体的HttpContext
(比如httpContextWrapper
) ,但其他实现可能与HttpContext
完全无关。
你最好的select是定义一个自定义的抽象工厂,可以为你获取一个HttpContextBase
,因为你总是可以将一个具体的HttpContext
包装在一个HttpContextWrapper
。