如何从 ASP.NET MVC 1 中的 HttpContextBase 获取 HttpContext 对象?

发布于 2024-08-16 05:46:40 字数 241 浏览 7 评论 0原文

我正在使用一些与 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

断爱 2024-08-23 05:46:40

最简单的方法是获取应用程序, ApplicationInstance,并使用其 < code>Context 属性:

// httpContextBase is of type HttpContextBase
HttpContext context = httpContextBase.ApplicationInstance.Context;

(感谢 Ishmael Smyrnow 注意到了这一点在评论中)

原始答案:

可以,特别是如果您收到的 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) { /* ... */ }

HttpContextBase 有一个名为 < code>GetService 由于支持 <代码>IServiceProviderHttpContextWrapperGetService 重写委托给包装的 HttpContext 实例的 GetService 实现。 HttpContextGetService 实现允许您查询常见的可疑内容,例如 HttpApplicationHttpRequestHttpResponse< /代码>等等。碰巧 HttpApplication 有一个名为 Context 并返回 HttpContext 的实例。因此,我们可以通过 GetServiceHttpContextBase 请求 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 its Context property:

// httpContextBase is of type HttpContextBase
HttpContext context = httpContextBase.ApplicationInstance.Context;

(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 type HttpContextWrapper at run-time. The following example illustrates how you can do this. It supposes you have a method called Foo that accepts context as HttpContextBase 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 as 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) { /* ... */ }

HttpContextBase has a method called GetService as a result of supporting IServiceProvider. The GetService override of HttpContextWrapper delegates to the GetService implementation of the wrapped HttpContext instance. The GetService implementation of HttpContext allows you to query for usual suspects like HttpApplication, HttpRequest, HttpResponse and so on. It just so happens that HttpApplication has a property called Context and which returns an instance of HttpContext. So one gets at the wrapped HttpContext instance by asking HttpContextBase for HttpApplication via GetService followed by reading the Context property of the returned HttpApplication instance.

Unlike HttpContextBase, GetService does not appear as a public member of HttpContext but that is because HttpContext implements IServiceProvider.GetService explicity while HttpContextBase doesn't.

Bear in mind that Foo is no longer testable because it relies on being able to unwrap the underlying HttpContext 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.

与君绝 2024-08-23 05:46:40

你可以,

var abstractContext = new System.Web.HttpContextWrapper(System.Web.HttpContext.Current);

You can,

var abstractContext = new System.Web.HttpContextWrapper(System.Web.HttpContext.Current);
流绪微梦 2024-08-23 05:46:40

你不能。

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

最好的选择是定义一个自定义抽象工厂,它可以为您获取 HttpContextBase ,因为您始终可以将具体的 HttpContext 包装在 HttpContextWrapper 中。

You can't.

The whole purpose of HttpContextBase is to abstract away the dependency on the concrete HttpContext class. While it may contain a concrete HttpContext (such as is the case with httpContextWrapper), other implementations may have absolutely nothing to do with HttpContext.

Your best option is to define a custom Abstract Factory that can get a HttpContextBase for you, since you can always wrap a concrete HttpContext in a HttpContextWrapper.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文