Нулевая сессия в конструкторах контроллера ASP.Net MVC - PullRequest
83 голосов
/ 20 мая 2009

Почему Session null в конструкторах контроллеров? Доступ к нему можно получить из методов действий. Предположительно, поскольку инфраструктура маршрутизации MVC отвечает за обновление контроллера, в этот момент она просто не (повторно) создала экземпляр сеанса.

Кто-нибудь знает, задумано ли это, и если да, то почему?

[Мне удалось обойти проблему, используя шаблон отложенной загрузки.]

Ответы [ 6 ]

72 голосов
/ 31 июля 2009

Андрей прав - это ноль, потому что при работе в рамках ASP.NET MVC HttpContext (и, следовательно, HttpContext.Session) не устанавливается, когда класс контроллера создается, как вы могли ожидать, но он устанавливает ( ") позже классом ControllerBuilder. Если вы хотите лучше понять жизненный цикл, вы можете либо свернуть каркас ASP.NET MVC (источник доступен), либо обратиться к: этой странице

Если вам нужен доступ к сеансу, то одним из способов будет переопределение метода «OnActionExecuting» и доступ к нему там, так как он будет доступен к тому времени.

Однако, как предполагает Андрей, если ваш код зависит от Session, тогда может быть сложно написать модульные тесты, поэтому, возможно, вы могли бы рассмотреть оборачивание Session в вспомогательный класс, который затем может быть заменен на другой , не веб-версия при работе в модульных тестах, поэтому отключение контроллера от сети.

55 голосов
/ 28 сентября 2012

В дополнение к другим ответам здесь, пока Controller.Session не заполнен в конструкторе, вы все равно можете получить доступ к сеансу через:

System.Web.HttpContext.Current.Session

со стандартным предупреждением, что это потенциально снижает тестируемость вашего контроллера.

10 голосов
/ 20 июня 2009

Сессия вводится позже в жизненном цикле. В любом случае, зачем вам сеанс в конструкторе? Если вам это нужно для TDD, вы должны обернуть сессию в макетный объект.

7 голосов
/ 02 мая 2014

Вы можете переопределить метод Initialize, чтобы установить сеанс.

protected override void Initialize(RequestContext requestContext)
2 голосов
/ 01 марта 2015

Если вы используете контейнер IoC, попробуйте ввести и использовать HttpSessionStateBase вместо Session объекта:

private static Container defaultContainer()
{
    return new Container(ioc =>
    {
        // session manager setup
        ioc.For<HttpSessionStateBase>()
           .Use(ctx => new HttpSessionStateWrapper(HttpContext.Current.Session)); 
    });
}
0 голосов
/ 19 июля 2018

Этот ответ может быть полезен для некоторых людей

Если мы переопределим метод Initialize, то мы должны инициализировать базовый класс с контекстом запроса: base.Initialize (requestContext);

protected override void Initialize(RequestContext requestContext)
        {
            base.Initialize(requestContext);
            if (web == null && Session != null && Session["APPLIANCE_URL"] != null)
            {
                web = new WebServices((String)Session["APPLIANCE_URL"]);
            }

        }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...