会话null在ASP.Net MVC控制器构造函数中

为什么在控制器的构造函数中会话是空的? 它可以从Action方法访问。 据推测,因为MVC路由框架负责新控制器,它没有(重新)实例化会议在这一点上。

有谁知道这是否是devise,如果是这样,为什么?

[我设法通过使用延迟加载模式来解决这个问题。]

Andrei是正确的 – 它是空的,因为当在ASP.NET MVC框架下运行时,HttpContext(因此HttpContext.Session)没有被设置,当控制器类被构造,如你所期望的,但它设置(“注入”)由ControllerBuilder类。 如果你想更好地理解生命周期,你可以下拉ASP.NET MVC框架(源代码可用),或者参考: 本页

如果您需要访问会话,则有一种方法是覆盖“OnActionExecuting”方法并在那里访问它,因为那个时候可用。

然而,正如Andrei所build议的那样,如果你的代码依赖于Session,那么编写unit testing可能会很困难,所以也许你可以考虑把Session包装在一个辅助类中,然后这个辅助类可以换出一个不同的,在unit testing下运行时使用Web版本,因此可以将控制器从Web上解耦。

除了这里的其他答案,虽然没有在构造函数中填充Controller.Session ,但仍然可以通过以下方式访问会话:

System.Web.HttpContext.Current.Session

与标准的警告,这可能会降低您的控制器的可testing性。

会话在生命周期的后期被注入。 为什么你需要在构造函数的会话吗? 如果你需要TDD,你应该把会话包装成一个可模仿的对象。

您可以重写Initialize方法来设置会话。

 protected override void Initialize(RequestContext requestContext) 

如果您正在使用IoC容器,请尝试注入并使用HttpSessionStateBase而不是Session对象:

 private static Container defaultContainer() {    return new Container(ioc =>    {        // session manager setup        ioc.For<HttpSessionStateBase>()           .Use(ctx => new HttpSessionStateWrapper(HttpContext.Current.Session));    }); }