Co należy zrobić, jeśli bieżąca sesja ASP.NET ma wartość NULL?

125

W mojej aplikacji internetowej robię coś takiego, aby odczytać zmienne sesji:

if (HttpContext.Current.Session != null &&  HttpContext.Current.Session["MyVariable"] != null)
{
    string myVariable= (string)HttpContext.Current.Session["MyVariable"];
}

Rozumiem, dlaczego ważne jest, aby sprawdzić, dlaczego HttpContext.Current.Session ["MyVariable"] ma wartość null (zmienna mogła nie zostać jeszcze zapisana w sesji lub sesja została zresetowana z różnych powodów), ale dlaczego muszę to sprawdzić jeśli HttpContext.Current.Sessionjest null?

Rozumiem, że sesja jest tworzona automatycznie przez ASP.NET, dlatego HttpContext.Current.Session nigdy nie powinna mieć wartości null. Czy to założenie jest słuszne? Jeśli może być zerowe, czy to znaczy, że powinienem to sprawdzić przed zapisaniem czegoś w nim:

if (HttpContext.Current.Session != null)
{
    HttpContext.Current.Session["MyVariable"]="Test";
}
else
{
    // What should be done in this case (if session is null)?
    // Is it possible to force the session to be created if it doesn't exist?
}
Anthony
źródło
ASP.NET WebApi będzie miał inne zachowanie, możesz to sprawdzić na
dostępie

Odpowiedzi:

158

Tak, obiekt Session może mieć wartość null, ale tylko w pewnych okolicznościach, z którymi będziesz się rzadko spotykać:

Jeśli masz kod tylko na stronach, nie napotkasz tego. Większość mojego kodu ASP .NET używa sesji bez wielokrotnego sprawdzania wartości null. Jest to jednak coś, o czym należy pomyśleć, jeśli tworzysz IHttpModule lub w inny sposób nie znasz bardziej szczegółowych informacji o ASP .NET.

Edytować

W odpowiedzi na komentarz: To, czy stan sesji jest dostępny, zależy od tego, czy zdarzenie AcquireRequestState zostało uruchomione dla żądania. W tym miejscu działa moduł stanu sesji, odczytując plik cookie sesji i znajdując dla Ciebie odpowiedni zestaw zmiennych sesji.

AcquireRequestState jest uruchamiany przed przekazaniem kontroli do strony. Więc jeśli wywołujesz inne funkcje, w tym klasy statyczne, ze swojej strony, wszystko powinno być w porządku.

Jeśli niektóre klasy wykonują logikę inicjowania podczas uruchamiania, na przykład w zdarzeniu Application_Start lub przy użyciu konstruktora statycznego, stan sesji może być niedostępny. Wszystko sprowadza się do tego, czy istnieje aktualne żądanie i czy AcquireRequestState zostało uruchomione.

Ponadto, jeśli klient wyłączył pliki cookie, obiekt Session będzie nadal dostępny - ale przy następnym żądaniu użytkownik powróci z nową, pustą sesją. Dzieje się tak, ponieważ klient otrzymuje pakiet stanu sesji, jeśli jeszcze go nie ma. Jeśli klient nie prześle pliku cookie sesji, nie mamy możliwości zidentyfikowania klienta jako takiego samego, więc będzie otrzymywał ciągle nową sesję.

driis
źródło
6
Tylko krótka aktualizacja, którą znalazłem dzisiaj. Sesja nie jest dostępna w konstruktorze strony! Tylko podczas wydarzenia Init lub później.
Nuno Agapito
Właśnie napotkałem HttpContext.Current.Session == null to kod wywoływany przez zdarzenie Page_Load strony wzorcowej. Najwyraźniej może to mieć miejsce w kontekście strony. Jeśli sprawdzę obiekt HttpContext.Current, większość jego członków jest zainicjowana, ale CurrentNotification i IsPostNotification generują błąd: {System.PlatformNotSupportedException}. Bez względu na przyczynę, problem ten nie wystąpił w produkcji, gdzie występuje od lat. Platforma to Windows Server 2003 R2 SP2, aplikacja ma docelową strukturę .Net 3.5 i działa w usługach IIS z włączonym stanem sesji.
R. Schreurs
Zauważyłem również, że gdy IIS obsługuje bezpośrednie żądanie pliku zasobów istniejącego na dysku, takiego jak arkusz stylów, HttpContext.Current.Sessionmoże mieć wartość zerową w kodzie w `Application_AcquireRequestState '. Żądanie samej strony powoduje jednak, że obiekt sesji jest tam dostępny do kodowania. Jest to przynajmniej w MVC.NET 4.
składnik_15939
Myślę, że może to być również null, jeśli znajdujesz się wewnątrz akcji MVC buforowanej na wyjściu.
user2173353
40

Poniższe stwierdzenie nie jest całkowicie poprawne:

„Więc jeśli wywołujesz inne funkcje, w tym klasy statyczne, ze swojej strony, wszystko powinno być w porządku”

Wzywam metodę statyczną, która odwołuje się do sesji za pośrednictwem HttpContext.Current.Session i jest null. Jednak wywołuję metodę za pośrednictwem metody usługi sieciowej za pośrednictwem AJAX przy użyciu jQuery.

Jak dowiedziałem się tutaj , możesz rozwiązać problem za pomocą prostego atrybutu w metodzie lub użyć obiektu sesji usługi sieciowej:

Jest jednak pewna sztuczka, aby uzyskać dostęp do stanu sesji w ramach metody internetowej, musisz włączyć zarządzanie stanem sesji w następujący sposób:

[WebMethod (EnableSession = true)]

Określając wartość EnableSession, będziesz mieć teraz zarządzaną sesję do zabawy. Jeśli nie określisz tej wartości, otrzymasz pusty obiekt Session i najprawdopodobniej napotkasz zerowe wyjątki odwołań podczas próby uzyskania dostępu do obiektu sesji.

Podziękowania dla Matthew Coziera za rozwiązanie.

Pomyślałem, że dodam moje dwa centy.

Ed

Ed Bishop
źródło
1
dzięki Ed, Sesja pojawiała się jako null w metodzie internetowej - dodanie tego rozwiązało problem. +1
fusi Kwietnia
1
Cóż, kiedy dzwonisz do usługi sieciowej, używasz innego żądania niż dla strony, więc to stwierdzenie jest nadal poprawne, IMO.
driis
Dokumenty MSDN tutaj - the default value is false. Działa jak marzenie.
Benjineer
22

Jeśli Twoja instancja Session ma wartość null, a znajdujesz się w pliku „ashx”, po prostu zaimplementuj interfejs „IRequiresSessionState”.

Ten interfejs nie ma żadnych członków, więc wystarczy dodać nazwę interfejsu po deklaracji klasy (C #):

public class MyAshxClass : IHttpHandler, IRequiresSessionState
mathijsuitmegen
źródło
Dziękuję bardzo, sesja w mojej klasie logowania była zerowa. Kiedy dodałem ten kod do mojego programu obsługi Ashx, włączyłem sesję również na mojej klasie
Ateş Danış
Myślę, że to całkiem dobrze odpowiada na pytanie. Dzięki wielkie.
Sachin Joseph
2

Artykuły techniczne dotyczące platformy ASP.NET

PODSUMOWANIE: W ASP.NET każda strona sieci Web pochodzi z klasy System.Web.UI.Page. Klasa Page agreguje wystąpienie obiektu HttpSession dla danych sesji. Klasa Page udostępnia różne zdarzenia i metody dostosowywania. W szczególności metoda OnInit służy do ustawiania stanu inicjalizacji obiektu Page. Jeśli żądanie nie zawiera pliku cookie sesji, do żądającego zostanie wysłany nowy plik cookie sesji.

EDYTOWAĆ:

Sesja: koncepcja dla początkujących

PODSUMOWANIE: Sesja jest tworzona, gdy użytkownik wysyła pierwsze żądanie do serwera dla dowolnej strony w aplikacji internetowej, aplikacja tworzy sesję i wysyła identyfikator sesji z powrotem do użytkownika z odpowiedzią i jest przechowywany na komputerze klienckim jako mały plik cookie . Idealnie byłoby więc, gdyby „maszyna, która wyłączyła pliki cookie, informacje o sesji nie będą przechowywane”.

adatapost
źródło
2

W moim przypadku ASP.NET State Servicezostał zatrzymany. Zmiana Startup typedo Automatici ręcznego uruchamiania usługi po raz pierwszy rozwiązany problem.

Eric
źródło