ManagedPipelineHandler для AJAX POST аварийно завершает работу, если пользователь IE9 уходит со страницы во время выполнения этого вызова.

Сценарий:

  • Пользователь использует IE9 (IE8/10 не затрагивается).
  • У пользователя есть активная сессия.
  • Страница запускает запрос AJAX POST (GET не затрагивается) к контроллеру с атрибутом SessionState(SessionStateBehavior.Required) (ReadOnly не затрагивается). Что-то препятствует немедленной обработке этого запроса (например, другой выполняемый запрос, который заблокировал сеанс).
  • Пока выполняется AJAX POST, пользователь уходит со страницы (GET или POST - не имеет значения)

Результат:

  • AJAX POST завершается и возвращает HTTP 500 (который браузер с тех пор перестал прослушивать, но вы можете увидеть его в журналах IIS). IIS Failed Request Tracing показывает ошибку: «Указанное сетевое имя больше недоступно. (0x80070040)».
  • Сеанс пользователя блокируется где-то между 80 и 120 секундами (обычно около 100), прежде чем может быть выполнен следующий запрос, требующий доступа к сеансу чтения/записи.

Дальнейшее изучение журнала, созданного трассировкой невыполненных запросов IIS, показывает, что AJAX POST дает сбой, подобный этому, после состояния сеанса заблокировано (во время фазы REQUEST_ACQUIRE_STATE), но поскольку фаза REQUEST_RELEASE_STATE не происходит, блокировка сеанса не снимается. Я предполагаю, что в игре есть какой-то механизм безопасности, который разблокирует сеанс через 80-120 секунд, но это очень долгое зависание явно нежелательно для моих пользователей.

У меня есть простой проект VS2012/.Net 4.5/MVC4, демонстрирующий проблему, доступную по адресу https://github.com/jorupp/Ie9SessionCrash. (есть одна страница, которая делает серию сообщений о действиях со спящими вызовами). Трассировка невыполненных запросов IIS, показывающая проблему, находится в проекте по адресу https://github.com/jorupp/Ie9SessionCrash/tree/master/Ie9SessionCrash/TraceOfHttp500.

Чтобы обойти эту проблему, мы планируем никогда не выполнять вызовы AJAX POST для действий, требующих сеанса, а также:

  • Использование вызовов GET, где это возможно
  • Использование POST-вызовов для контроллеров с атрибутом SessionState(SessionStateBehavior.ReadOnly).

Есть ли лучший способ справиться с этим, или мне не хватает патча IIS/.Net в связи с этим? Или этот сценарий недействителен по какой-то другой причине? Я не решаюсь винить в этом фреймворк/IIS, но я думаю, что устранил ошибку моего кода.


person Jonathan Rupp    schedule 15.03.2013    source источник
comment
Просто чтобы вы знали, проблема, вероятно, также затрагивает IE7 и IE8. У нас есть система [медленное исправление], в которой мы обнаружили подобное поведение с этими двумя браузерами. Проблема, по-видимому, вызвана незавершенным Ajax-запросом, который завершается после того, как браузер переключил страницу. Мы можем обойти это, явно отменив запрос. Я не могу подтвердить, что это именно эта проблема, пока клиент (с высокой степенью защиты) не исправит рассматриваемые системы, но это точно соответствует MO этого.   -  person philw    schedule 27.06.2014
comment
@philw: конкретный способ, которым мы заставили его сломать .Net 4.5 (до обходного пути или исправления, упомянутого Леви), не произошел с IE8, но может быть другой способ вызвать эту ситуацию (браузер завершает запрос в середине потока) .   -  person Jonathan Rupp    schedule 27.06.2014
comment
Понял. Однако мы подтвердили это как на IE7, так и на IE8 — установка патча MS исправила это именно так, как и ожидалось. В нашем случае проблема была именно в том, что запрос в полете возвращается после того, как браузер перестал его слушать. Мы все еще видим это (ошибка 64 в логах сервера), но это больше не убивает IE7 и IE8, теперь мы пропатчили сервер.   -  person philw    schedule 11.07.2014


Ответы (2)


Это похоже на регрессию в ASP.NET 4.5. Наша команда работает над исправлением, но в качестве временного решения попробуйте поместить эту строку в Web.config (дополнительная информация здесь):

<system.webServer>
  <serverRuntime uploadReadAheadSize="0" />
</system.webServer>

Пожалуйста, дайте нам знать, если это работает для вас!

person Levi    schedule 18.03.2013
comment
Мне пришлось обновить файл applicationhost.config для моего экземпляра IISExpress, чтобы разблокировать его, но это помогло. Спасибо за помощь. Использование классического режима также сработало, но я надеялся, что мне не придется заходить так далеко. - person Jonathan Rupp; 19.03.2013
comment
Кстати, большое спасибо за логи! Они действительно помогли нам быстро решить эту проблему. :) - person Levi; 19.03.2013
comment
всегда пожалуйста - вы быстро решили эту проблему для меня, опубликовав ее на SO и даже не удосужившись открыть что-то для этого в Connect. Похоже, вам, ребята, скучно, и вы активно ищете что можно исправить :) - person Jonathan Rupp; 19.03.2013
comment
Это то, что также может быть проблемой в .NET 4.0 или только в .NET 4.5? Мы наблюдаем нечто подобное в .NET 4.0 и тестируем обновление до 4.5.1, но не уверены, решит ли это проблему или нет, поскольку мы еще не работаем с .NET 4.5. - person Bernd; 12.03.2014
comment
Бернд, конкретная проблема, вызвавшая проблемы, описанные в этом посте, относится только к версии 4.5. Это было исправлено в 4.5.1. Если вы видите проблему в 4.0, откройте новый вопрос SO. - person Levi; 12.03.2014
comment
@Levi любое обновление для этой проблемы. Ссылки на исправление не работают. Любые обновления, пожалуйста. Я пробовал ‹serverRuntime uploadReadAheadSize=0 /›, он не работает в IIS 7.5. - person Bilgin Kılıç; 10.01.2019

Ответ Леви отлично работает в IIS 7.5 или выше. Но если вы используете Server 2008 R1, следующая команда также установит этот параметр:

c:\windows\system32\inetsrv\appcmd.exe set config "sitename" -section:system.webServer/serverRuntime /uploadReadAheadSize:"0" /commit:apphost 

Но лучшее решение — применить исправление от Microsoft, которое устраняет проблему (№ 6 в прикрепленной статье базы знаний).

http://support.microsoft.com/kb/2828841/EN-US
http://support.microsoft.com/kb/2828842/EN-US< /а>

person Matt J    schedule 15.07.2013
comment
не удалось загрузить исправление. - person Bilgin Kılıç; 10.01.2019