Как "Требуется SSL" влияет на жизненный цикл приложения ASP.NET MVC?
У меня есть приложение, которое подключается к BeginRequest
а также EndRequest
настроить и разорвать сеансы NHibernate следующим образом:
BeginRequest += delegate
{
CurrentSessionContext.Bind(SessionFactory.OpenSession());
};
EndRequest += delegate
{
var session = CurrentSessionContext.Unbind(SessionFactory);
session.Dispose();
Container.Release(session);
};
Это прекрасно работает при развертывании в IIS, пока я не установлю флажок "Требовать SSL". Как только я это сделаю, я получу NullReferenceException
в session.Dispose()
,
Я еще не отлаживал это, и да, исправление тривиально, но мне просто интересно, как "Require SSL" влияет на жизненный цикл запроса. Не установлен ли сеанс на сервере в этих случаях?
РЕДАКТИРОВАТЬ: просто чтобы уточнить, я имею в виду параметр "Требовать SSL" в конфигурации IIS для приложения, а не RequireHttps
атрибут для контроллеров.
2 ответа
Этот пробудил мое любопытство, поэтому я немного в него покопался; извините за некромантию.
Я создал простой проект, который связывал уведомления для каждого события жизненного цикла объекта приложения и устанавливал точки останова для каждого из них.
Оказывается, когда установлен параметр "Требовать SSL" и вы получаете доступ без SSL, большинство событий полностью пропускаются. Первое событие, чтобы выстрелить LogRequest
, с последующим PostLogRequest
, EndRequest
, PreSendRequestContent
, а также PreSendRequestHeaders
(в этой последовательности). Другие события не запускаются.
Таким образом, ваш код был сбой, потому что BeginRequest
событие никогда не было запущено, и EndRequest
делегат пытался Dispose()
то, что никогда не было создано.
Что мне интересно, так это выяснить, почему IIS ведет себя так. Я подозреваю, что причина в том, что IIS по-прежнему необходимо регистрировать недопустимые попытки подключения, а также отправлять содержимое и заголовки, даже если запрашиваемый ресурс требует SSL. Что-то должно генерировать эту дружественную "запрещенную" страницу, в конце концов. Что я не знаю, почему EndRequest
называется вообще, когда они не удосужились позвонить BeginRequest
; Я предполагаю, что есть некоторый код очистки IIS/ASP, который зависит от этого.
Это поведение зависит от того, работает ли пул приложений в "Интегрированном" или "Классическом" режиме. В "классическом" режиме все события ASP.NET запускаются "между" IIS PreRequestHandlerExecute
а также PostRequestHandlerExecute
События. Вы не сказали, что работали, но это должно быть интегрировано; в противном случае вы бы увидели ожидаемое вами поведение, т.е. ни один из вашего кода не был бы выполнен вообще.
Интересно, что если вы попытаетесь подписаться на LogRequest
, PostLogRequest
, или же MapRequestHandler
события в классическом режиме, вы получаете исключение во время выполнения; это только "имеет смысл" в контексте интегрированного конвейера.
Here is something that might help you
Обзор жизненного цикла приложений ASP.NET для IIS 5.0 и 6.0
Обзор жизненного цикла приложений ASP.NET для IIS 7.0
You might want to do what you are doing in global.asax instead.