如何从ASP.NET MVC 1中的HttpContextBase获取HttpContext对象?
我正在使用一些WebForms / MVC不可知论的工具,我需要得到一个HttpContext的实例给定一个HttpContextBase对象的引用。 我不能使用HttpContext.Current因为我需要这个asynchronous工作( HttpContext.Currentasynchronous请求期间返回null )。 我知道HttpContextWrapper ,但错误的方式。
最简单的方法是获取应用程序ApplicationInstance并使用其Context属性:
// httpContextBase is of type HttpContextBase HttpContext context = httpContextBase.ApplicationInstance.Context;
(感谢Ishmael Smyrnow在评论中提到这一点)
原始答案:
你可以,特别是如果你已经交给的HttpContextBase实例在运行时是HttpContextWrappertypes的话。 以下示例说明如何执行此操作。 它假设你有一个名为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 。