如何从 ASP.NET MVC 1 中的 HttpContextBase 获取 HttpContext 对象?
我正在使用一些与 WebForms/MVC 无关的工具,并且需要获取一个 HttpContext 实例,并给出对 HttpContextBase 对象的引用。我无法使用 HttpContext.Current
因为我也需要它异步工作(HttpContext.Current
在异步请求期间返回 null
)。我知道 HttpContextWrapper
,但走错了路。
I'm working with some WebForms/MVC-agnostic tools, and I need to get an instance of HttpContext
given a reference to an HttpContextBase
object. I can't use HttpContext.Current
because I need this to work asynchronously as well (HttpContext.Current
returns null
during an asynchronous request). I'm aware of HttpContextWrapper
, but goes the wrong way.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
最简单的方法是获取应用程序,
ApplicationInstance
,并使用其 < code>Context 属性:(感谢 Ishmael Smyrnow 注意到了这一点在评论中)
原始答案:
可以,特别是如果您收到的
HttpContextBase
实例的类型为HttpContextWrapper
在运行时。以下示例说明了如何执行此操作。它假设您有一个名为Foo
的方法,该方法接受上下文作为HttpContextBase
但随后需要调用第三方程序集中的方法(您可能没有足够的运气)修改),期望上下文类型为HttpContext
。HttpContextBase
有一个名为 < code>GetService 由于支持 <代码>IServiceProvider。HttpContextWrapper
的GetService
重写委托给包装的HttpContext
实例的GetService
实现。HttpContext
的GetService
实现允许您查询常见的可疑内容,例如HttpApplication
、HttpRequest
、HttpResponse< /代码>等等。碰巧
HttpApplication
有一个名为 Context 并返回HttpContext
的实例。因此,我们可以通过GetService
向HttpContextBase
请求HttpApplication
来获取包装的HttpContext
实例,然后读取返回的 HttpApplication 实例的 Context
属性。与
HttpContextBase
不同,GetService
不会显示为HttpContext
的公共成员,但这是因为HttpContext
实现了IServiceProvider.GetService
显式,而HttpContextBase
则不然。请记住,
Foo
不再是可测试的,因为它依赖于在测试期间能够解开底层HttpContext
,而这从一开始就几乎不可能伪造/存根。然而,这个答案的重点是解决这个问题:“如何从 HttpContextBase 获取 HttpContext 对象?”,字面上。当您发现自己夹在您不一定有能力修改的组件之间时,所展示的技术非常有用。The simplest way is to get the application,
ApplicationInstance
, and use itsContext
property:(thanks to Ishmael Smyrnow who noted this in the comments)
Original answer:
You can, especially if the
HttpContextBase
instance you've been handed is of typeHttpContextWrapper
at run-time. The following example illustrates how you can do this. It supposes you have a method calledFoo
that accepts context asHttpContextBase
but 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 asHttpContext
.HttpContextBase
has a method calledGetService
as a result of supportingIServiceProvider
. TheGetService
override ofHttpContextWrapper
delegates to theGetService
implementation of the wrappedHttpContext
instance. TheGetService
implementation ofHttpContext
allows you to query for usual suspects likeHttpApplication
,HttpRequest
,HttpResponse
and so on. It just so happens thatHttpApplication
has a property called Context and which returns an instance ofHttpContext
. So one gets at the wrappedHttpContext
instance by askingHttpContextBase
forHttpApplication
viaGetService
followed by reading theContext
property of the returnedHttpApplication
instance.Unlike
HttpContextBase
,GetService
does not appear as a public member ofHttpContext
but that is becauseHttpContext
implementsIServiceProvider.GetService
explicity whileHttpContextBase
doesn't.Bear in mind that
Foo
is no longer testable because it relies on being able to unwrap the underlyingHttpContext
during 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.你可以,
You can,
你不能。
HttpContextBase
的全部目的是抽象出对具体HttpContext
类的依赖。虽然它可能包含具体的HttpContext
(例如httpContextWrapper
的情况),其他实现可能绝对有与 HttpContext 无关。最好的选择是定义一个自定义抽象工厂,它可以为您获取 HttpContextBase ,因为您始终可以将具体的 HttpContext 包装在 HttpContextWrapper 中。
You can't.
The whole purpose of
HttpContextBase
is to abstract away the dependency on the concreteHttpContext
class. While it may contain a concreteHttpContext
(such as is the case withhttpContextWrapper
), other implementations may have absolutely nothing to do withHttpContext
.Your best option is to define a custom Abstract Factory that can get a
HttpContextBase
for you, since you can always wrap a concreteHttpContext
in aHttpContextWrapper
.