2013-03-15 26 views
6

Scenariusz:ManagedPipelineHandler dla AJAX POST zawiesza się, jeśli użytkownik nawiguje IE9 od strony natomiast, że telefon był w toku

  • użytkownik korzysta IE9 (IE8/10 nie dotyczy).
  • Użytkownik ma aktywną sesję.
  • Strona uruchamia żądanie AJAX POST (GET niezatwierdzone) do kontrolera z atrybutem SessionState(SessionStateBehavior.Required) (ReadOnly nie dotyczy). Coś sprawia, że ​​żądanie to nie jest natychmiast przetwarzane (np. Inne żądanie będące w toku, które ma zablokowaną sesję).
  • Mimo że AJAX POST jest w toku, użytkownik nawiguje od strony (GET lub POST - nie ma znaczenia)

Wynik:

  • AJAX POST kończy i wraca HTTP 500 (od tej pory przeglądarka przestała nasłuchiwać, ale można to zobaczyć w dziennikach IIS). Nieudane żądanie IIS Śledzenie pokazuje błąd: "Określona nazwa sieci nie jest już dostępna. (0x80070040)."
  • Sesja użytkownika jest zablokowana na czas od 80 do 120 sekund (zwykle około 100), zanim kolejne żądanie, które wymaga dostępu do sesji odczytu/zapisu, może zostać wykonane.

Dalsze kopanie w dzienniku stworzonej przez IIS Failed Zapytanie Tracing oznacza, że ​​AJAX POST zawiesza tak po stan sesja została zamknięta (podczas fazy REQUEST_ACQUIRE_STATE), ale ponieważ faza REQUEST_RELEASE_STATE nie dzieje , blokada sesji nie została zwolniona. Zakładam, że w trakcie gry jest jakiś mechanizm bezpieczeństwa, który odblokowuje sesję po 80-120 sekundach, ale to bardzo długie zawieszenie jest oczywiście niepożądane dla moich użytkowników.

Mam prosty projekt VS2012/.Net 4.5/MVC4 demonstrujący problem dostępny pod adresem https://github.com/jorupp/Ie9SessionCrash (ma jedną stronę, która tworzy serię wpisów do działań z połączeniami Sleep). Śledzenie żądań IIS nieudane pokazujące problem znajduje się w projekcie pod numerem https://github.com/jorupp/Ie9SessionCrash/tree/master/Ie9SessionCrash/TraceOfHttp500.

Aby obejść ten problem, planujemy, aby zapewnić, że nigdy nie dokonywać żadnych AJAX POST wzywa do działań, które wymagają sesji, i albo:

  • Korzystanie połączeń gdzie możliwe
  • GET POST przy użyciu połączenia do kontrolerów, które mają atrybut SessionState(SessionStateBehavior.ReadOnly).

Czy jest lepszy sposób radzenia sobie z tym, czy też brakuje mi łatki IIS/.Net w związku z tym? A może ten scenariusz nie jest ważny z innego powodu? Waham się za to winić frameworka/IIS, ale myślę, że wyeliminowałem mój kod z winy.

+0

tak wiesz, problem prawdopodobnie dotyczy IE7 i IE8 również. Mamy system [powolny do łatania], w którym odkryliśmy takie zachowanie w przypadku tych dwóch przeglądarek. Problem wydaje się być spowodowany przez zaległe żądanie Ajax, które zakończyło się po zmianie strony przeglądarki. Możemy obejść go, wyraźnie anulując żądanie. Nie mogę potwierdzić, że to jest właśnie ta kwestia, dopóki ("bardzo bezpieczny") klient nie załatwi omawianych systemów, ale dokładnie zgadza się z MO. – philw

+0

@philw: specyficzny sposób, w jaki próbowaliśmy go złamać .Net 4.5 (przed obejściem lub łatką, o której wspomniał Levi) nie wystąpił w IE8, ale może istnieć inny sposób wywołania tej sytuacji (przeglądarka przerywa żądanie w połowie strumienia). –

+0

Zrozumiano. Potwierdziliśmy to jednak zarówno w IE7, jak i IE8 - zainstalowanie poprawki MS poprawiło ją dokładnie zgodnie z oczekiwaniami. W naszym przypadku problem polegał właśnie na tym, że "żądanie lotu powróciło po tym, jak przeglądarka przestała go słuchać". Wciąż to widzimy (błąd 64 w logach serwera), ale nie zabija już IE7 i IE8, teraz załataliśmy serwer. – philw

Odpowiedz

5

Wygląda na to, że jest to regresja w programie ASP.NET 4.5. Nasz zespół pracuje nad patchem, ale jako tymczasowe obejście spróbować umieścić tę linię w pliku web.config (więcej here):

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

Daj nam znać, jeśli działa dla Ciebie!

+0

Musiałem zaktualizować plik applicationhost.config dla mojej instancji IISExpress, aby ją odblokować, ale to wystarczyło. Dzięki za pomoc. Używanie trybu klasycznego również działało, ale miałem nadzieję, że nie będę musiał posunąć się tak daleko. –

+0

BTW, wielkie dzięki za dzienniki! Naprawdę pomogli nam szybko rozwiązać ten problem. :) – Levi

+0

Nie ma za co - rozwiązałeś to szybko dla mnie, wysyłając go do SO, a nawet nie zadając sobie trudu, aby otworzyć coś w Connect dla tego. To prawie tak, jakbyście się nudzili i wybrali * aktywnie wyglądający * dla rzeczy do naprawienia :) –

1

Odpowiedź Levi'ego sprawdza się świetnie w IIS 7.5 lub nowszym.Ale jeśli używasz Server 2008 R1, następujące polecenie będzie również wybrać ustawienie:

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

ale lepszym rozwiązaniem jest zastosowanie poprawki firmy Microsoft, które środki emisji (nr 6 w załączonym artykule KB)

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