asp.net-mvc 如何从 ASP.NET MVC 1 中的 HttpContextBase 获取 HttpContext 对象?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1992141/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How do I get an HttpContext object from HttpContextBase in ASP.NET MVC 1?
提问by Daniel Schaffer
I'm working with some WebForms/MVC-agnostic tools, and I need to get an instance of HttpContextgiven a reference to an HttpContextBaseobject. I can't use HttpContext.Currentbecause I need this to work asynchronously as well (HttpContext.Currentreturns nullduring an asynchronous request). I'm aware of HttpContextWrapper, but goes the wrong way.
我正在使用一些 WebForms/MVC-agnostic 工具,我需要获取一个HttpContext给定HttpContextBase对象引用的实例。我无法使用,HttpContext.Current因为我也需要它异步工作(在异步请求期间HttpContext.Current返回null)。我知道HttpContextWrapper,但走错了路。
回答by Atif Aziz
The simplest way is to get the application, ApplicationInstance, and use its Contextproperty:
最简单的方法是获取应用程序ApplicationInstance,并使用其Context属性:
// httpContextBase is of type HttpContextBase
HttpContext context = httpContextBase.ApplicationInstance.Context;
(thanks to Ishmael Smyrnowwho noted this in the comments)
(感谢Ishmael Smyrnow在评论中指出这一点)
Original answer:
原答案:
You can, especially if the HttpContextBaseinstance you've been handed is of type HttpContextWrapperat run-time. The following example illustrates how you can do this. It supposes you have a method called Foothat accepts context as HttpContextBasebut then needs to call a method in a third-party assembly (that you may not have the good fortune to modify) that is expecting the context to be typed as HttpContext.
您可以,特别是如果HttpContextBase您收到的实例是HttpContextWrapper运行时的类型。以下示例说明了如何执行此操作。它假设您有一个被调用的方法,该方法Foo接受上下文为,HttpContextBase但随后需要调用第三方程序集中的方法(您可能没有好运进行修改),该方法期望将上下文输入为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) { /* ... */ }
HttpContextBasehas a method called GetServiceas a result of supporting IServiceProvider. The GetServiceoverride of HttpContextWrapperdelegates to the GetServiceimplementation of the wrapped HttpContextinstance. The GetServiceimplementation of HttpContextallows you to query for usual suspects like HttpApplication, HttpRequest, HttpResponseand so on. It just so happens that HttpApplicationhas a property called Contextand which returns an instance of HttpContext. So one gets at the wrapped HttpContextinstance by asking HttpContextBasefor HttpApplicationvia GetServicefollowed by reading the Contextproperty of the returned HttpApplicationinstance.
HttpContextBase有一个方法被调用GetService作为支持的结果IServiceProvider。对包装实例实现GetService的HttpContextWrapper委托的覆盖。该实施允许您查询秋后算账一样,,等等。碰巧它有一个名为Context的属性,它返回. 因此,人们在包裹得例如通过询问对通过随后通过读取返回的财产情况。GetServiceHttpContextGetServiceHttpContextHttpApplicationHttpRequestHttpResponseHttpApplicationHttpContextHttpContextHttpContextBaseHttpApplicationGetServiceContextHttpApplication
Unlike HttpContextBase, GetServicedoes not appear as a public member of HttpContextbut that is because HttpContextimplements IServiceProvider.GetServiceexplicity while HttpContextBasedoesn't.
与 不同HttpContextBase,GetService, 不显示为 的公共成员,HttpContext但那是因为显式HttpContext实现IServiceProvider.GetService而HttpContextBase没有。
Bear in mind that Foois no longer testable because it relies on being able to unwrap the underlying HttpContextduring testing and which is next to impossible to fake/stub in the first place. The point of this answer, however, is to address the question, “How do I get an HttpContext object from HttpContextBase?”, literally. The illustrated technique is useful in those situations where you find yourself sandwiched between components you don't necessarily have the luxury to modify.
请记住,这Foo不再是可测试的,因为它依赖于能够HttpContext在测试期间解开底层,而这几乎不可能首先伪造/存根。然而,这个答案的重点是解决这个问题,“我如何从 HttpContextBase 获取 HttpContext 对象?”,字面意思是。图示的技术在您发现自己夹在您不一定有机会修改的组件之间的情况下很有用。
回答by Marc Chouteau
You can,
你可以,
var abstractContext = new System.Web.HttpContextWrapper(System.Web.HttpContext.Current);
回答by Mark Seemann
You can't.
你不能。
The whole purpose of HttpContextBaseis to abstract away the dependency on the concrete HttpContextclass. While it maycontain a concrete HttpContext(such as is the case with httpContextWrapper), other implementations may have absolutely nothing to do with HttpContext.
的全部目的HttpContextBase是抽象掉对具体HttpContext类的依赖。虽然它可能包含一个具体的HttpContext(例如与 的情况httpContextWrapper),但其他实现可能与 完全无关HttpContext。
Your best option is to define a custom Abstract Factory that can get a HttpContextBasefor you, since you can always wrap a concrete HttpContextin a HttpContextWrapper.
您最好的选择是定义一个可以HttpContextBase为您获取 a 的自定义抽象工厂,因为您始终可以将具体HttpContext的HttpContextWrapper.

