Сессия null в конструкторах диспетчера ASP.NET MVC
Почему Session null в конструкторах контроллеров? Доступ к нему возможен из методов Action. Предположительно, поскольку структура MVC Routing отвечает за создание контроллера контроллера, он просто не выполнил (повторно) создание сеанса в этой точке.
Кто-нибудь знает, если это по дизайну, и если да, то почему?
[Мне удалось обойти проблему, используя шаблон Lazy Loading.]
Ответы
Ответ 1
Андрей прав - это нулевое значение, потому что при работе в рамках ASP.NET MVC HttpContext (и, следовательно, HttpContext.Session) не задается, когда класс контроллера строится так, как вы могли ожидать, но он устанавливал ( "вводил" ) позже классом ControllerBuilder. Если вы хотите лучше понять жизненный цикл, вы можете либо вывести структуру ASP.NET MVC (источник доступен), либо обратиться к: этой странице
Если вам нужно получить доступ к сеансу, одним из способов было бы переопределить метод "OnActionExecuting" и получить к нему доступ, так как он будет доступен к этому времени.
Однако, как указывает Андрей, если ваш код зависит от сеанса, тогда потенциально может быть трудно написать модульные тесты, поэтому, возможно, вы можете рассмотреть возможность переноса сеанса в вспомогательный класс, который затем может быть заменен на другой, не веб-версию при работе в модульных тестах, поэтому удаление вашего контроллера из Интернета.
Ответ 2
В дополнение к другим ответам здесь, в то время как Controller.Session
не заполняется в конструкторе, вы можете получить доступ к сеансу через:
System.Web.HttpContext.Current.Session
со стандартным предупреждением о том, что это потенциально снижает вашу тестируемость контроллера.
Ответ 3
Сессия вводится позже в жизненном цикле. Зачем вам нужен сеанс в конструкторе? Если вам это нужно для TDD, вы должны перенести сеанс в макетируемый объект.
Ответ 4
Вы можете переопределить метод Initialize, чтобы установить сеанс.
protected override void Initialize(RequestContext requestContext)
Ответ 5
Если вы используете контейнер IoC, попробуйте ввести и использовать HttpSessionStateBase
вместо объекта Session
:
private static Container defaultContainer()
{
return new Container(ioc =>
{
// session manager setup
ioc.For<HttpSessionStateBase>()
.Use(ctx => new HttpSessionStateWrapper(HttpContext.Current.Session));
});
}