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


154

我正在使用某些与WebForms / MVC无关的工具,并且需要获取HttpContext给定HttpContextBase对象引用的实例。我无法使用,HttpContext.Current因为我还需要它也能异步工作(在异步请求期间HttpContext.Current返回null)。我知道HttpContextWrapper,但是走错了路。

Answers:


249

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

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

(感谢Ishmael Smyrnow在评论中指出了这一点)

原始答案:

您可以这样做,尤其是如果HttpContextBase您处理的实例HttpContextWrapper在运行时是类型的。以下示例说明了如何执行此操作。假设您有一个名为的方法Foo,它接受context作为,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有个GetService由于支持而被称为的方法IServiceProvider。在GetService的覆盖HttpContextWrapper委托给GetService包裹的执行HttpContext情况。该GetService实施HttpContext允许您查询秋后算账一样HttpApplicationHttpRequestHttpResponse等等。碰巧HttpApplication有一个名为Context的属性,该属性返回的实例HttpContext。因此,人们在包裹得HttpContext例如通过询问HttpContextBaseHttpApplication通过GetService随后通过读取Context返回的财产HttpApplication情况。

与不同HttpContextBaseGetService不会显示为的公共成员,HttpContext但这是因为HttpContext实现IServiceProvider.GetService显式而HttpContextBase没有。

请记住,Foo它不再是可测试的,因为它依赖于能够HttpContext在测试过程中解开底层的内容,并且几乎不可能首先伪造/存根。这个答案的要点,但是,是要解决问题,“我如何从一个HttpContextBase HttpContext对象?”,从字面上。在您发现自己被夹在组件之间的情况下,图示的技术很有用。


3
非常有趣的答案,我自己在MVC中使用了它,将HttpContext从错误过滤器传递给ELMAH进行记录。
克里斯·马里西奇

1
好的答案,下注需要一点点挖掘吗?:)
longhairedsi

好答案!我利用的特别是在我ELMAH到MVC控制器github.com/alexanderbeletsky/elmah.mvc.controller/blob/master/...
亚历山大Beletsky

35
使用HttpContextBase,您不能打电话context.ApplicationInstance.Context吗?
Ishmael Smyrnow 2011年

@IshmaelSmyrnow哎呀,不要错过我在所有Http*Base返回的变体中错过的那个HttpContextBase。:P我将更新答案。
阿提夫·阿齐兹

32

您可以,

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

16
-1这是错误的方法,当您具有上下文时,这将为您提供基础,而不是相反。
克里斯·马里西奇

14

你不能

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

最好的选择是定义一个自定义的Abstract Factory,它可以HttpContextBase为您提供,因为您始终可以将混凝土包裹HttpContext在中HttpContextWrapper


12
顺便说一句,这是可怕的事情-我理解想要为单元测试设置,并且我理解抽象层-但是当您想使用期望使用HttpContext的现有ASP.NET类时,应该执行WTH吗?(像msdn.microsoft.com/en-us/library/...
MARQ

是的,要测试IHttpHandler实现,您最终不得不在(Response包装器)中仅为单元测试添加一定数量的抽象,虽然感觉不对,但最终是唯一的选择。
克里斯S
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.