Ho un'applicazione WebForms ASP.NET 4.0. Devo accedere a HttpContext.Current.Session
e impostare un valore nell'evento AcquireRequestState
in Global.asax (o un evento successivo) e ho riscontrato un comportamento particolare.La sessione è nullo in AcquireRequestState quando si carica il nome della directory virtuale nel browser, ma non è null durante il caricamento di Default.aspx
Supponiamo di avere una directory virtuale in IIS (versione 7 nel mio caso) denominata . In questo ho Default.aspx
come pagina iniziale. Un esempio di file Global.asax
è qui sotto:
<%@ Application Language="C#" %>
<script runat="server">
void Application_AcquireRequestState(object sender, EventArgs e)
{
HttpContext.Current.Session["key"] = "value";
}
</script>
Quando visito http://localhost/Foo/Default.aspx
nel mio browser, funziona bene. Quando visito lo http://localhost/Foo/
ottengo un NullReferenceException
dove imposto il valore sulla sessione. L'unica modifica è l'URL nel browser. Finiscono per colpire la stessa pagina, ma il framework si comporta diversamente in base al fatto che l'URL contenga o meno un nome di cartella o se contenga un file aspx.
Il controllo if (HttpContext.Current.Session != null)
non è un'opzione per me, perché è necessario impostare un valore sulla sessione con ogni richiesta, che non è negoziabile.
Esiste un'impostazione di configurazione in IIS che mi manca oppure è una funzionalità di bug/dimenticata?
Una risposta per another question ha accennato al fatto che IIS non carica la sessione per ogni tipo di richiesta, ad esempio i fogli di stile non hanno bisogno di una sessione. Forse questo comportamento sta accadendo perché IIS non può dire in anticipo se quel nome di cartella risulterà nell'esecuzione di un file aspx o se fornirà un file HTML statico?
Aggiornamento: Ho persino provato a riordinare i documenti predefiniti che IIS cerca in modo che "default.aspx" fosse in cima alla lista, ad es.
- default.aspx
- default.ASP
- Default.htm
- ...
E sto ancora ricevendo lo stesso problema.
Aggiornamento:
Il gestore eventi viene solo essere stato licenziato una volta perché si traduce in un NullReferenceException
. Ho effettuato alcune letture aggiuntive e so che ASP.NET attiva questi eventi per ogni richiesta, anche per i file CSS o JavaScript. Inoltre, l'oggetto della sessione non viene caricato per i file statici perché non esiste il codice che accede alla sessione, quindi non è necessario caricare l'oggetto. Anche così, la prima richiesta è la richiesta per la pagina web, che richiederà la sessione, e la sessione è nullo.
@DmytroShevchenko chiesto:
Prima aggiungere un controllo di guardia
if (HttpContext.Current.Session != null)
in modo che non ci siaNullReferenceException
gettato. Quindi prova a vedere, forse l'evento verrà licenziato una seconda volta, con una sessione disponibile.
Codice modificato:
void Application_AcquireRequestState(object sender, EventArgs e)
{
if (HttpContext.Current.Session != null)
{
HttpContext.Current.Session["key"] = "value";
}
}
ho impostato un punto di interruzione la dichiarazione if
. Ho visto questo evento fuoco 4 volte:
- sessione è nullo sessione
- è nullo
- sessione non nullo
- sessione è nullo
Quando continuando ad eseguire il codice ogni volta, solo quando ha iniziato l'esecuzione di Default.aspx
e il suo code-behind ho avuto una sessione disponibile. In realtà avevo la pagina web aperta in Firefox e stavo monitorando le richieste di rete. La prima richiesta era per http://localhost/Foo/
.
Poi ho impostato un punto di interruzione in Application_BeginRequest
come bene e ha ottenuto i seguenti eventi:
- BeginRequest
- AcquireRequestState
- BeginRequest
- AcquireRequestState
- BeginRequest
- AcquireRequestState (sessione non è null)
- Eseguire Default.aspx (/ Foo restituisce una risposta al browser)
- BeginRequest
- AcquireRequestState (sessione è ancora nulla)
al # 9 della richiesta AJAX nel browser per 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
è appeso in attesa di una risposta.
cosa succede se si aggiunge il controllo 'if (HttpContext.Current.Session! = Null)' e mettere un debugger per la linea che mette un nuovo valore nella sessione? Forse questo evento viene eseguito due volte per questa richiesta? Una volta senza una sessione e una volta con una sessione? –
Anche quando inserisco un punto di interruzione, la sessione è nullo. Ho trovato una soluzione alternativa, ma non una causa principale. Se la sessione è nullo, reindirizzo l'utente a /Default.aspx dove è disponibile la sessione. –
Capisco che la sessione è nullo. Quello che sto chiedendo è se questo evento viene licenziato più di una volta per richieste a 'http: // localhost/Foo /'. –