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

Dan*_*fer 151 asp.net-mvc httpcontext

我正在使用一些WebForms/MVC无关的工具,我需要获得一个HttpContext给定HttpContextBase对象引用的实例.我无法使用,HttpContext.Current因为我需要它也可以异步工作(在异步请求期间HttpContext.Current返回null).我知道HttpContextWrapper,但走错了路.

Ati*_*ziz 239

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

// httpContextBase is of type HttpContextBase
HttpContext context = httpContextBase.ApplicationInstance.Context;
Run Code Online (Sandbox Code Playgroud)

(感谢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) { /* ... */ }
Run Code Online (Sandbox Code Playgroud)

HttpContextBase有一个被GetService称为支持的方法IServiceProvider.在GetService的覆盖HttpContextWrapper委托给GetService包裹的执行HttpContext情况.该GetService实施HttpContext允许您查询秋后算账一样HttpApplication,HttpRequest,HttpResponse等等.碰巧HttpApplication有一个名为Context的属性,它返回一个实例HttpContext.因此,人们在包裹得HttpContext例如通过询问HttpContextBaseHttpApplication通过GetService随后通过读取Context返回的财产HttpApplication情况.

不同HttpContextBase,GetService它不是作为公共成员出现,HttpContext而是因为HttpContext实现IServiceProvider.GetService明确而HttpContextBase不是.

请记住,Foo它不再是可测试的,因为它依赖于能够HttpContext在测试期间解包底层,并且几乎不可能首先伪造/存根.然而,这个答案的要点是解决这个问题,"如何从HttpContextBase中获取HttpContext对象?",字面意思.图解技术在您发现自己夹在不一定要修改的组件之间的情况下非常有用.

  • 使用HttpContextBase,你不能调用`context.ApplicationInstance.Context`吗? (34认同)
  • 非常有趣的答案,我自己在MVC中使用它将HttpContext从错误过滤器传递给ELMAH进行日志记录. (3认同)

小智 30

您可以,

var abstractContext = new System.Web.HttpContextWrapper(System.Web.HttpContext.Current);
Run Code Online (Sandbox Code Playgroud)

  • +1 ......没有回答这个问题......但它帮助了我! (34认同)
  • -1这是错误的方法,当你有上下文时,这会给你Base,而不是相反. (16认同)

Mar*_*ann 14

你不能.

整个目的HttpContextBase是抽象出对具体HttpContext类的依赖.虽然它可能包含一个具体的HttpContext (例如情况httpContextWrapper),但其他实现可能完全没有任何关系HttpContext.

您最好的选择是定义一个可以HttpContextBase为您获取的自定义抽象工厂,因为您始终可以将混凝土包装HttpContext在一个HttpContextWrapper.

  • 顺便说一下,这是非常糟糕的 - 我理解想要有一个单元测试的设置,我理解抽象层 - 但是当你想使用期望HttpContext的现有ASP.NET类时,你应该做什么?(如http://msdn.microsoft.com/en-us/library/system.web.sessionstate.sessionidmanager.aspx) (12认同)