2012-01-20 13 views
26

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.

risposta

9

~/campione/settest? Value = foo

Sì non sarà gettare alcun errore, ma anche non persistere la sessione al termine della richiesta.In base alla progettazione, qualsiasi cosa che scrivi alla sessione viene aggiornata (solo se la sessione è scrivibile) alla fine del ciclo di vita della richiesta.

Nel mio test ~/Sample/Test non restituisce nulla.

Penso che avrebbero dovuto fallire velocemente qui quando la sessione è in sola lettura.

Tra l'altro il campione ha bisogno di essere riscritto

string test = (string)this.Session["test"]; 
+0

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

+0

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

+0

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

Problemi correlati