У меня есть приложение ASP.NET 4.0 WebForms. Мне нужно получить доступ к HttpContext.Current.Session
и установить значение в событии AcquireRequestState
(или событие после него) в Global.asax, и я нашел своеобразное поведение.
Скажем, у меня есть виртуальный каталог в IIS (версия 7 в моем случае) под названием Foo
. При этом Default.aspx
. Пример файла Global.asax
ниже:
<%@ Application Language="C#" %>
<script runat="server">
void Application_AcquireRequestState(object sender, EventArgs e)
{
HttpContext.Current.Session["key"] = "value";
}
</script>
Когда я посещаю http://localhost/Foo/Default.aspx
в моем браузере, он работает отлично. Когда я посещаю http://localhost/Foo/
, я получаю NullReferenceException
, где я устанавливаю значение в сеансе. Единственное изменение - это URL в браузере. Они попадают на одну и ту же страницу, но структура ведет себя по-разному, основываясь на том, содержит ли URL только имя папки или содержит файл aspx.
Проверка if (HttpContext.Current.Session != null)
для меня не является опцией, потому что мне нужно установить значение в сеансе с каждым запросом, который не подлежит обсуждению.
Есть ли в IIS параметр конфигурации, который мне не хватает, или это ошибка/забытая функция?
Ответ на еще один вопрос намекнул на то, что IIS не загружает сеанс для каждого вида запроса, например, таблицы стилей не нуждаются в сеансе. Возможно, такое поведение происходит, потому что IIS не может сказать заранее, если это имя папки приведет к выполнению aspx файла или если он предоставит статический HTML файл?
Обновление: Я даже попробовал переупорядочить документы по умолчанию, которые IIS ищет, чтобы "default.aspx" находился в верхней части списка, например
- default.aspx
- Default.asp
- Default.htm
- ...
И я все еще получаю ту же проблему.
Update:
Обработчик событий запускается только один раз, потому что он приводит к NullReferenceException
. Я сделал некоторое дополнительное чтение, и я знаю, что ASP.NET запускает эти события для каждого запроса, даже для файлов CSS или JavaScript. Кроме того, объект сеанса не загружается для статических файлов, потому что нет кода, который обращается к сеансу, поэтому нет необходимости загружать объект. Тем не менее, самый первый запрос - это запрос на веб-страницу, для которой потребуется сеанс, а сеанс имеет значение null.
@Дмитрий Шевченко спросил:
Сначала добавьте проверочный чек
if (HttpContext.Current.Session != null)
, чтобы не было выброшеноNullReferenceException
. Затем попробуйте увидеть, возможно, событие будет запущено во второй раз, с сеансом.
Измененный код:
void Application_AcquireRequestState(object sender, EventArgs e)
{
if (HttpContext.Current.Session != null)
{
HttpContext.Current.Session["key"] = "value";
}
}
Я установил точку прерывания в выражении if
. Я видел это событие четыре раза:
- session is null
- session is null
- сеанс не null
- session is null
Когда вы продолжаете каждый раз переходить к коду, только когда он начал выполнять Default.aspx
и его код, у меня есть сеанс. У меня на самом деле была открыта веб-страница в Firefox и она отслеживала сетевые запросы. Первый запрос был для http://localhost/Foo/
.
Далее я установил точку останова в Application_BeginRequest
и получил следующие события:
- BeginRequest
- AcquireRequestState
- BeginRequest
- AcquireRequestState
- BeginRequest
- AcquireRequestState (сеанс не является нулевым)
- Выполнить Default.aspx(/Foo возвращает ответ браузеру)
- BeginRequest
- AcquireRequestState (сеанс снова null)
В # 9 запрос AJAX в браузере http://localhost:54859/8fad4e71e57a4caebe1c6ed7af6f583a/arterySignalR/poll?transport=longPolling&connectionToken=...&messageId=...&requestUrl=http%3A%2F%2Flocalhost%2FFoo%2F&browserName=Firefox&userAgent=Mozilla%2F5.0+(Windows+NT+6.1%3B+WOW64%3B+rv%3A41.0)+Gecko%2F20100101+Firefox%2F41.0&tid=4&_=1445346977956
висит в ожидании ответа.