题 在ASP.net MVC中,控制器实例上的HttpContext为null


这可能不是使用控制器的正确方法,但我确实注意到了这个问题并且没有找到纠正它的方法。

public JsonResult SomeControllerAction() {

    //The current method has the HttpContext just fine
    bool currentIsNotNull = (this.HttpContext == null); //which is false    

    //creating a new instance of another controller
    SomeOtherController controller = new SomeOtherController();
    bool isNull = (controller.HttpContext == null); // which is true

    //The actual HttpContext is fine in both
    bool notNull = (System.Web.HttpContext.Current == null); // which is false        

}

我注意到Controller上的HttpContext不是你在System.Web.HttpContext.Current中找到的“实际”HttpContext。

有没有办法在Controller上手动填充HttpContextBase?或者更好的方法来创建Controller的实例?


26
2017-10-21 20:12


起源




答案:


控制器不是设计为像您一样手动创建的。听起来你应该做的就是将你拥有的任何可重用逻辑放入一个帮助类中。


24
2017-10-22 14:19



Brad,你有什么地方可以帮助理解MVC设计和最佳实践吗?到目前为止,MVC一直很酷,但我发现的大多数例子都不是很复杂。它们只涉及更新单个记录等简单实例。 - Hugoware
布拉德,我有同样的问题,这也是来自帮助类,就像你推荐的那样。我尝试了Hugoware提供的修复程序(下面),并修复了它。这是正确的方法吗? - Mark Kadlec


现在我要做以下事情。这似乎是一个可接受的解决方案......

public new HttpContextBase HttpContext {
    get {
        HttpContextWrapper context = 
            new HttpContextWrapper(System.Web.HttpContext.Current);
        return (HttpContextBase)context;                
    }
}

如果将其添加到Controller类,则这些控制器将继承自。

我不确定HttpContext是否为null是期望的行为,但是这将在此期间修复它。


61
2017-10-22 14:13



非常感谢您破解这两种类型之间的新工作方式。我有一个旧类,我试图使用一个消耗HttpContext对象的MVC控制器。现在我有一个类,它使用一个带有构造函数重载的HttpContextBase对象,它将使用你提到的HttpContextWrapper构造函数在HttpContext和HttpContextBase之间进行转换。 - patridge
是的,我也想感谢你破译这个! - Funka
+1精彩帖子。一直在寻找这个。 - magnus
现场解决方案! - Ollie
+1这是一个很棒的片段!我加入了一点。我用一个ContextHelper类包装你的包装器,它只从我的底层HttpContext proeprty中暴露出我需要的属性,然后允许我创建一个我的ContextHelper的模拟。然后StructureMap允许我交换我需要的东西。然后我创建了一个WebSite对象作为视图API,它暴露在视图,控制器等各种基类之外。如果你不这样做,我将不得不在我的书(ASP.NET MVC Cookbook)中提到这一点。心神: groups.google.com/group/aspnet-mvc-2-cookbook-review - Andrew Siemer


ControllerContext中的HttpContext为null,因为在创建控制器时未设置它。控制器的构造函数不分配此属性,因此它将为null。通常,HttpContext设置为ControllerBuilder类的HttpContext。控制器由ControllerBuilder类创建,后跟DefaultControllerFactory。如果要创建自己的控制器实例,可以使用控制器的ExecuteMethod和自己的ControllerContext。你不想这样做是一个真正的应用程序。当您获得更多使用该框架的经验时,您将找到适合您想要的方法。当您在单元测试中需要ControllerContext时,您可以使用模拟框架来模拟ControllerContext,或者您可以对其进行伪造。

您可以在asp.net mvc on上找到请求流的模型 这个博客

当您刚接触Asp.net mvc时,值得努力下载源代码并读取跟踪请求的处理方式。


5
2017-10-21 22:44





是否要使用控制器中的某些功能?或让控制器执行操作?

如果它是前者,那么可能是某些代码应该拆分成另一个类。如果是后者,您可以执行此操作以简单地让控制器执行特定操作:


return RedirectToAction("SomeAction", "SomeOtherController", new {param1 = "Something" });


0
2017-10-21 20:17





你在使用控制器工厂吗?如果是这样,您如何注册组件?

我遇到了这个问题,我无意中将一个基于HttpContext的依赖项添加为Singleton,而不是Windsor中的Transient。

除第一个请求外,HttpContext为null。我花了一段时间来追踪那一个。


0
2017-10-22 13:50