Ho riscontrato un comportamento curioso delle sessioni ASP. È possibile forzare un controller ad essere al di fuori della sessione dell'utente: voglio essere in grado di farlo in modo che più richieste possano essere eseguite contemporaneamente e l'utilizzo di una sessione ne consenta l'esecuzione consecutiva.Scrittura in una sessione di sola lettura in MVC 3+
Disabilitare sessione opere statali come previsto:
[SessionState(SessionStateBehavior.Disabled)]
public class SampleController : Controller
{
public ActionResult Test()
{
// Access to the session should be denied
object test = Session["test"];
return Content(test);
}
}
Andando a ~/campione/Test getteranno un System.Web.HttpException
, come previsto. Tuttavia, le sessioni di sola lettura sembrano comportarsi in modo un po 'strano:
[SessionState(SessionStateBehavior.ReadOnly)]
public class SampleController : Controller
{
public ActionResult Test()
{
// Read from the session should be fine
object test = Session["test"];
return Content(test);
}
public ActionResult SetTest(string value)
{
// Write to the session should fail
Session["test"] = value;
// Read it back from the session
object test = Session["test"];
return Content(test);
}
}
Così ora mi aspetto ~/campione/Test al lavoro, e lo fa. La cosa strana è che anche il set lo fa: vado a ~/Sample/SetTest? Value = foo e non lancia un'eccezione, infatti restituisce "foo". Se chiamo ~/Sample/SetTest? Value = bar e quindi ~/Sample/Test Ottengo "bar", a indicare che la sessione è stata scritta.
Così in un SessionStateBehavior.ReadOnly
ho scritto con successo alla sessione e leggere il mio valore indietro.
credo che questo potrebbe essere dovuto a una delle tre cose:
- In MVC 3
[SessionState(SessionStateBehavior.ReadOnly)]
è rotto/ignorato. - Il
[SessionState]
viene sovrascritto quando la sessione viene scritta e diventa scrivibile. - Il
SessionStateBehavior.ReadOnly
indica effettivamente una sorta di accesso sporco/ottimistico.
Qualcuno può confermare?
Sospetto che l'ultimo sia vero, basato sullo custom session provider documentation - se è così, come funziona l'implementazione? La scrittura in una sessione di "sola lettura" rischia di errori di concorrenza (ad esempio, l'ultima scrittura vince) o rischia di corrompere le sessioni e di interrompere le eccezioni?
Aggiornamento
Sembra che questo è di progettazione (da Microsoft's docs):
Nota che, anche se l'attributo EnableSessionState è contrassegnato come ReadOnly, altre pagine ASP.NET nella stessa l'applicazione potrebbe essere in grado di scrivere nell'archivio di sessione, pertanto una richiesta per i dati di sessione di sola lettura dall'archivio potrebbe ancora attendere che i dati bloccati vengano liberati.
Sembra che la seconda opzione sopra sia ciò che effettivamente fa: la sessione è bloccata e la modalità è modificata in scrittura.
Hmm, il campione qui è semplificato codice per quello che sto facendo, ma sto ottenendo la sessione scritto - chiamando _ ~/Sample/settest ? value = foo_ e quindi _ ~/Sample/Test_ sta restituendo "foo" per me. In realtà dovrebbe essere un errore, e se non dovrebbe semplicemente fallire nel salvare la sessione, ma è sicuramente un risparmio per me. – Keith
Hai ragione, il mio esempio nella domanda non riesce a scrivere nella sessione, come previsto. La domanda è: perché la mia app è ancora in grado di scrivere su di essa? Scoprirò cosa è diverso e aggiorno la domanda ... – Keith
come ho detto nella mia risposta sopra, non stanno fallendo velocemente quando la sessione è di sola lettura e quando la si aggiorna. Il framework sta semplicemente ignorando l'aggiornamento della sessione alla fine della richiesta. Nel frattempo ti permettono di modificare la struttura della sessione in qualsiasi modo ti piaccia. – chandmk