Cosa devo fare se la sessione ASP.NET corrente è nulla?


125

Nella mia applicazione web, faccio qualcosa del genere per leggere le variabili di sessione:

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

Capisco perché è importante controllare perché HttpContext.Current.Session ["MyVariable"] è nullo (la variabile potrebbe non essere stata ancora memorizzata nella sessione o la sessione è stata reimpostata per vari motivi), ma perché devo controllare se HttpContext.Current.Sessionè nullo?

La mia comprensione è che la sessione viene creata automaticamente da ASP.NET quindi HttpContext.Current.Session non dovrebbe mai essere nullo. Questa ipotesi è corretta? Se può essere nullo, significa che dovrei anche controllarlo prima di memorizzare qualcosa al suo interno:

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?
}

ASP.NET WebApi avrà un comportamento diverso, puoi verificarlo su Accesso alla sessione utilizzando ASP.NET Web API
Tiago Gouvêa

Risposte:


158

Sì, l'oggetto Session potrebbe essere nullo, ma solo in determinate circostanze, in cui ti imbatterai solo raramente:

Se hai solo codice nelle pagine, non ti imbatterai in questo. La maggior parte del mio codice ASP .NET utilizza Session senza verificare ripetutamente la presenza di null. Tuttavia, è qualcosa a cui pensare se si sta sviluppando un IHttpModule o se si è nei dettagli più grintosi di ASP .NET.

modificare

In risposta al commento: se lo stato della sessione è disponibile o meno dipende dal fatto che l'evento AcquireRequestState sia stato eseguito per la richiesta. È qui che il modulo di stato della sessione funziona leggendo il cookie di sessione e trovando l'insieme appropriato di variabili di sessione per te.

AcquireRequestState viene eseguito prima che il controllo venga passato alla tua pagina. Quindi, se stai chiamando altre funzionalità, comprese le classi statiche, dalla tua pagina, dovresti stare bene.

Se alcune classi eseguono la logica di inizializzazione durante l'avvio, ad esempio sull'evento Application_Start o utilizzando un costruttore statico, lo stato della sessione potrebbe non essere disponibile. Tutto si riduce al fatto che sia presente una richiesta corrente e che AcquireRequestState sia stato eseguito.

Inoltre, se il client ha disabilitato i cookie, l'oggetto Session sarà ancora disponibile, ma alla richiesta successiva l'utente tornerà con una nuova Session vuota. Questo perché al client viene fornito uno stato Session se non ne ha già uno. Se il client non trasporta il cookie di sessione, non abbiamo modo di identificare il client come lo stesso, quindi gli verrà assegnata una nuova sessione ancora e ancora.


6
Solo un rapido aggiornamento che ho trovato oggi. La sessione non è disponibile nel costruttore della pagina! Solo nell'evento Init o dopo quello.
Nuno Agapito

Ho appena riscontrato un HttpContext.Current.Session == null è un codice chiamato da un evento Page_Load di una pagina master. Apparentemente, questo può verificarsi nel contesto di una pagina. Se ispeziono l'oggetto HttpContext.Current, la maggior parte dei membri viene inizializzata, ma CurrentNotification e IsPostNotification generano un errore: {System.PlatformNotSupportedException}. Qualunque sia la causa, questo problema non si è verificato in produzione, dove dura da anni. La piattaforma è Windows Server 2003 R2 SP2, l'applicazione ha framework di destinazione .Net 3.5 e viene eseguita in IIS con lo stato della sessione abilitato.
R. Schreurs

Ho anche scoperto che, quando IIS sta servendo una richiesta diretta per un file di risorse che esiste su disco, come un foglio di stile, HttpContext.Current.Sessionpuò essere nullo per il codice in "Application_AcquireRequestState". La richiesta per la pagina stessa, tuttavia, rende l'oggetto sessione disponibile per il codice lì. Questo è almeno sotto MVC.NET 4.
ingrediente_15939

Penso che potrebbe anche essere nullo se ci si trova all'interno di un'azione MVC nella cache di output.
user2173353

40

La seguente affermazione non è del tutto accurata:

"Quindi, se stai chiamando altre funzionalità, comprese le classi statiche, dalla tua pagina, dovresti stare bene"

Sto chiamando un metodo statico che fa riferimento alla sessione tramite HttpContext.Current.Session ed è nullo. Tuttavia, sto chiamando il metodo tramite un metodo webservice tramite Ajax utilizzando jQuery.

Come ho scoperto qui puoi risolvere il problema con un semplice attributo sul metodo, oppure utilizzare l'oggetto sessione del servizio web:

C'è un trucco però, per accedere allo stato della sessione all'interno di un metodo web, devi abilitare la gestione dello stato della sessione in questo modo:

[WebMethod (EnableSession = true)]

Specificando il valore EnableSession, ora avrai una sessione gestita con cui giocare. Se non specifichi questo valore, otterrai un oggetto Session nullo e molto probabilmente ti imbatterai in eccezioni di riferimento nullo durante il tentativo di accedere all'oggetto sessione.

Grazie a Matthew Cozier per la soluzione.

Ho solo pensato di aggiungere i miei due centesimi.

Ed


1
grazie Ed, la sessione appariva come nulla nel metodo web - l'aggiunta di questo lo ha risolto. +1
fusi

1
Bene, quando chiami in un servizio web, usi un'altra richiesta rispetto alla pagina, quindi quell'affermazione è ancora corretta, IMO.
driis

Documenti MSDN qui - the default value is false. Funziona come un fascino.
Benjineer

22

Se la tua istanza Session è nulla e ti trovi in ​​un file "ashx", implementa semplicemente l'interfaccia "IRequiresSessionState".

Questa interfaccia non ha membri, quindi è sufficiente aggiungere il nome dell'interfaccia dopo la dichiarazione della classe (C #):

public class MyAshxClass : IHttpHandler, IRequiresSessionState

Grazie mille, la sessione era nulla nella mia classe di accesso. Quando ho aggiunto questo codice al mio gestore ashx, la sessione è stata attivata anche nella mia classe
Ateş Danış

Penso che questo risponda abbastanza bene alla domanda. Grazie mille.
Sachin Joseph

2

Articoli tecnici su ASP.NET

SOMMARIO: In ASP.NET, ogni pagina Web deriva dalla classe System.Web.UI.Page. La classe Page aggrega un'istanza dell'oggetto HttpSession per i dati di sessione. La classe Page espone diversi eventi e metodi per la personalizzazione. In particolare, il metodo OnInit viene utilizzato per impostare lo stato di inizializzazione dell'oggetto Page. Se la richiesta non ha il cookie di sessione, al richiedente verrà emesso un nuovo cookie di sessione.

MODIFICARE:

Sessione: un concetto per principianti

SOMMARIO: La sessione viene creata quando l'utente invia una prima richiesta al server per qualsiasi pagina nell'applicazione web, l'applicazione crea la sessione e invia l'ID della sessione all'utente con la risposta e viene memorizzata nella macchina client come un piccolo cookie . Quindi idealmente la "macchina che ha disabilitato i cookie, le informazioni sulla sessione non verranno memorizzate".


2

Nel mio caso è ASP.NET State Servicestato fermato. Cambiare la Startup typea Automatice avviare il servizio manualmente per la prima volta ha risolto il problema.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.