Implementazione di un provider dell'archivio dello stato sessione
Aggiornamento: novembre 2007
Viene descritta l'implementazione di un provider dell'archivio dello stato sessione personalizzato e viene illustrata l'implementazione di un provider di esempio.
Lo stato sessione ASP.NET è progettato per facilitare l'archiviazione dei dati della sessione utente in differenti origini. Per impostazione predefinita, le informazioni e i valori relativi allo stato sessione vengono archiviati in memoria all'interno del processo ASP.NET. In alternativa, è possibile eseguire l'archiviazione in un server di stato. In questo caso i dati della sessione vengono collocati in un processo distinto e rimangono in memoria anche se l'applicazione ASP.NET viene chiusa e riavviata. Un'ulteriore soluzione consiste nell'archiviare i dati della sessione in un database SQL Server, dove possono essere condivisi da più server Web.
È possibile utilizzare gli archivi dello stato sessione forniti con ASP.NET oppure implementare un provider dell'archivio dello stato sessione personalizzato. È possibile creare un provider dell'archivio dello stato sessione personalizzato per i motivi seguenti:
Le informazioni relative allo stato sessione devono essere archiviate in un'origine dati diversa da SQL Server, ad esempio un database FoxPro o Oracle.
Le informazioni relative allo stato sessione devono essere gestite utilizzando uno schema di database che sia differente da quello utilizzato dai provider forniti con .NET Framework. Un caso tipico è rappresentato dai dati relativi a un carrello della spesa archiviati con uno schema predefinito nel database SQL Server esistente.
È possibile implementare un provider dell'archivio dello stato sessione personalizzato creando una classe che erediti la classe SessionStateStoreProviderBase. Per ulteriori informazioni, vedere la sezione "Classi obbligatorie" più avanti in questo argomento.
Modulo dello stato sessione
La stato sessione è gestito dalla classe SessionStateModule, che chiama il provider dell'archivio dello stato sessione per leggere e scrivere i dati della sessione nell'archivio dati in momenti diversi durante l'esecuzione di una richiesta. All'inizio di una richiesta, l'istanza SessionStateModule recupera i dati dall'origine dati chiamando il metodo GetItemExclusive o il metodo GetItem se l'attributo di pagina EnableSessionState è stato impostato su ReadOnly. Alla fine di una richiesta, se i valori dello stato sessione sono stati modificati, l'istanza SessionStateModule chiama il metodo SessionStateStoreProviderBase.SetAndReleaseItemExclusive per scrivere i valori aggiornati nell'archivio dello stato sessione. L'istanza SessionStateModule chiama membri aggiuntivi dell'implementazione SessionStateStoreProviderBase per inizializzare una nuova sessione ed eliminare i dati della sessione dall'archivio dati quando viene chiamato il metodo HttpSessionState.Abandon. Ciascun membro della classe SessionStateStoreProviderBase verrà illustrato dettagliatamente nella sezione "Classi obbligatorie" più avanti in questo argomento.
Il valore SessionID viene determinato direttamente dalla classe SessionStateModule anziché dal provider dell'archivio dello stato sessione. Se necessario, è possibile implementare una classe SessionIDManager personalizzata creando una classe che erediti l'interfaccia ISessionIDManager. Per ulteriori informazioni, vedere la sezione "Note" in ISessionIDManager.
La classe SessionStateModule tornerà all'identità del processo ASP.NET per accedere a qualsiasi risorsa sicura, ad esempio un server database. È possibile specificare che l'istanza SessionStateModule rappresenti l'identità fornita da IIS impostando l'attributo useHostingIdentity dell'elemento di configurazione <sessionState> su false. Se ad esempio l'applicazione IIS è stata configurata per l'utilizzo della sicurezza integrata di Windows e si desidera che ASP.NET rappresenti l'identità fornita da IIS per la gestione della sessione, specificare <identity impersonate="true" /> nella sezione di configurazione <system.web> del file Web.config per l'applicazione e impostare l'attributo useHostingIdentity dell'elemento di configurazione <sessionState> su false. Se l'attributo useHostingIdentity è impostato su true, ASP.NET rappresenterà l'identità del processo o le eventuali credenziali utente fornite all'elemento di configurazione <identity> al momento della connessione all'origine dati. Per ulteriori informazioni sull'identità del processo ASP.NET, vedere Configurazione dell'identità dei processi ASP.NET e Rappresentazione ASP.NET.
Blocco dell'archivio dati della sessione
Le applicazioni ASP.NET sono applicazioni multithreading e sono quindi in grado di rispondere a più richieste simultaneamente. È possibile che più richieste simultanee tentino di accedere alle stesse informazioni sulla sessione. Si consideri uno scenario in cui più frame in un set di frame fanno riferimento a pagine Web ASP.NET nella stessa applicazione. Le singole richieste per ciascun frame incluso nel set possono essere eseguite sul server Web contemporaneamente su thread differenti. Se le pagine ASP.NET relative a ciascun frame accedono a variabili dello stato sessione, è possibile che più thread accedano contemporaneamente all'archivio della sessione. Per evitare il conflitto di dati nell'archivio della sessione e un comportamento imprevisto dello stato sessione, le classi SessionStateModule e SessionStateStoreProviderBase includono una funzionalità che blocca in modo esclusivo l'elemento dell'archivio di una sessione specifica durante l'esecuzione di una pagina ASP.NET. Se l'attributo EnableSessionState è contrassegnato come ReadOnly, su un elemento dell'archivio della sessione non viene impostato alcun blocco. Tuttavia, poiché altre pagine ASP.NET nella stessa applicazione possono essere in grado di scrivere nell'archivio della sessione, è possibile che una richiesta di dati della sessione in sola lettura dall'archivio possa essere eseguita solo dopo lo sblocco dei dati.
Il blocco dei dati dell'archivio di una sessione viene impostato all'inizio della richiesta quando viene chiamato il metodo GetItemExclusive. Quando la richiesta viene completata, il blocco viene disattivato durante la chiamata al metodo SetAndReleaseItemExclusive.
Se l'istanza SessionStateModule rileva dei dati di sessione bloccati durante la chiamata al metodo GetItemExclusive o GetItem, i dati della sessione verranno nuovamente richiesti a intervalli di mezzo secondo fino a quando il blocco non verrà disattivato o l'intervallo di tempo specificato nella proprietà ExecutionTimeout non sarà trascorso. Se si verifica il timeout della richiesta, l'istanza SessionStateModule chiama il metodo ReleaseItemExclusive per sbloccare e richiedere i dati dell'archivio della sessione.
È possibile che i dati dell'archivio della sessione siano stati sbloccati da una chiamata al metodo ReleaseItemExclusive su un thread distinto prima della chiamata al metodo SetAndReleaseItemExclusive per la risposta corrente. In questo caso può accadere che l'istanza SessionStateModule imposti e sblocchi dei dati dell'archivio dello stato sessione che sono già stati sbloccati e modificati da un'altra sessione. Per impedire questa situazione, in ciascuna richiesta di modifica di dati bloccati l'istanza SessionStateModule include un identificatore di blocco. I dati dell'archivio della sessione vengono modificati solo se l'identificatore nell'archivio dati corrisponde all'identificatore fornito dall'istanza SessionStateModule.
Eliminazione di dati dell'archivio sessione scaduti
Quando viene chiamato il metodo Abandon per una sessione, i dati relativi a tale sessione vengono eliminati dall'archivio utilizzando il metodo RemoveItem. In caso contrario, i dati rimarranno nell'archivio dati per soddisfare future richieste della sessione.
Il meccanismo di eliminazione dei dati sessione scaduti dipende dalle funzionalità dell'origine dati utilizzata. Se l'origine dati può essere configurata per eliminare i dati di sessione scaduti in base alla proprietà Timeout della sessione, è possibile utilizzare il metodo SetItemExpireCallback per fare riferimento al delegato per l'evento Session_OnEnd e generare tale evento al momento dell'eliminazione dei dati sessione scaduti.
ApplicationName
Per mantenere l'ambito sessione, i provider dello stato sessione archiviano le informazioni sulla sessione in modo univoco per ciascuna applicazione. Questo consente a più applicazioni ASP.NET di utilizzare la stessa origine dati senza generare un conflitto nel caso in cui vengano rilevati identificatori di sessione duplicati.
Poiché le informazioni sulla sessione vengono archiviate in modo univoco per ciascuna applicazione, è necessario accertarsi che lo schema dati, le query e gli aggiornamenti includano il nome dell'applicazione. Il comando riportato di seguito, ad esempio, viene utilizzato per recuperare i dati della sessione da un database.
SELECT * FROM Sessions
WHERE SessionID = 'ABC123' AND ApplicationName = 'MyApplication'
In alternativa, è possibile archiviare una combinazione dell'identificatore di sessione e del nome dell'applicazione come identificatore univoco per un elemento dell'archivio dati dello stato sessione.
Classi obbligatorie
Per implementare un provider dell'archivio dello stato sessione, creare una classe che erediti la classe astratta SessionStateStoreProviderBase. Poiché la classe SessionStateStoreProviderBase eredita a sua volta la classe astratta ProviderBase, è necessario implementare anche i membri obbligatori della classe ProviderBase. Nelle tabelle riportate di seguito sono elencate le proprietà e i metodi che devono essere implementati dalle classi astratte ProviderBase e SessionStateStoreProviderBase, unitamente alla relativa descrizione. Per visualizzare un'implementazione di ciascun membro, vedere Provider dell'archivio dello stato sessione di esempio.
Membri di ProviderBase obbligatori
Membro |
Descrizione |
---|---|
Metodo Initialize |
Accetta come input il nome del provider e un'istanza NameValueCollection di impostazioni di configurazione. Viene utilizzato per impostare i valori delle proprietà per l'istanza di provider, inclusi i valori specifici dell'implementazione e le opzioni specificate nel file di configurazione (Machine.config o Web.config). |
Membri di SessionStateStoreProvider obbligatori
Membro |
Descrizione |
---|---|
Metodo InitializeRequest |
Accetta come input l'istanza HttpContext per la richiesta corrente ed esegue le inizializzazioni richieste dal provider dell'archivio dello stato sessione. |
Metodo EndRequest |
Accetta come input l'istanza HttpContext per la richiesta corrente ed esegue le operazioni di pulitura richieste dal provider dell'archivio dello stato sessione. |
Metodo Dispose |
Sblocca tutte le risorse non più utilizzate dal provider dell'archivio dello stato sessione. |
Metodo GetItemExclusive |
Accetta come input l'istanza HttpContext per la richiesta corrente e il valore SessionID per la richiesta corrente. Recupera informazioni e valori della sessione dall'archivio dati della sessione e blocca i dati dell'elemento della sessione nell'archivio dati per la durata della richiesta. Il metodo GetItemExclusive imposta diversi valori dei parametri di output che comunicano alla classe SessionStateModule chiamante lo stato dell'elemento dello stato sessione corrente nell'archivio dati. Se nell'archivio dati non viene trovato alcun dato relativo alla sessione, il metodo GetItemExclusive imposta il parametro di output locked su false e restituisce un valore null. L'istanza SessionStateModule chiama quindi il metodo CreateNewStoreData per creare un nuovo oggetto SessionStateStoreData per la richiesta. Se nell'archivio dati vengono rilevati dei dati relativi alla sessione, ma tali dati risultano bloccati, il metodo GetItemExclusive imposta il parametro di output locked su true, il parametro di output lockAge sulla data e ora correnti meno la data e l'ora in cui i dati sono stati bloccati, il parametro di output lockId sull'identificatore di blocco recuperato dall'archivio dati, quindi restituisce un valore null. Di conseguenza, l'istanza SessionStateModule chiama nuovamente il metodo GetItemExclusive dopo un intervallo di mezzo secondo per tentare di recuperare le informazioni sulla sessione e ottenere un blocco sui dati. Se il valore sul quale è impostato il parametro di output lockAge supera il valore ExecutionTimeout, l'istanza SessionStateModule chiamerà il metodo ReleaseItemExclusive per rimuovere il blocco sui dati della sessione, quindi nuovamente il metodo GetItemExclusive. Il parametro actionFlags viene utilizzato con sessioni la cui proprietà Cookieless è impostata su true, quando l'attributo regenerateExpiredSessionId viene impostato su true. Un valore actionFlags impostato su InitializeItem (1) indica che la voce nell'archivio dati della sessione è una nuova sessione che richiede l'inizializzazione. Le voci non inizializzate nell'archivio dati della sessione vengono create da una chiamata al metodo CreateUninitializedItem. Se la voce dell'archivio dati della sessione è già inizializzata, il parametro actionFlags sarà impostato su zero. Se il provider in uso supporta sessioni senza cookie, impostare il parametro di output actionFlags sul valore restituito dall'archivio dati della sessione per l'elemento corrente. Se il valore del parametro actionFlags per l'elemento dell'archivio della sessione richiesto equivale al valore di enumerazione InitializeItem (1), il metodo GetItemExclusive dovrebbe impostare il valore nell'archivio dati su zero dopo l'impostazione del parametro actionFlagsout. |
Metodo GetItem |
Questo metodo esegue le stesse operazioni del metodo GetItemExclusive, tranne per il fatto che non viene effettuato alcun tentativo per bloccare i dati della sessione nell'archivio dati. Il metodo GetItem viene chiamato quando l'attributo EnableSessionState è impostato su ReadOnly. |
Metodo SetAndReleaseItemExclusive |
Accetta come input l'istanza HttpContext per la richiesta corrente, il valore SessionID per la richiesta corrente, un oggetto SessionStateStoreData che contiene i valori della sessione corrente da archiviare, l'identificatore di blocco per la richiesta corrente e un valore che indica se i dati da archiviare si riferiscono a una nuova sessione o a una esistente. Se il parametro newItem è impostato su true, il metodo SetAndReleaseItemExclusive inserisce un nuovo elemento nell'archivio dati con i valori forniti. In caso contrario, l'elemento esistente nell'archivio dati viene aggiornato con i valori forniti, quindi il blocco dei dati viene disattivato. Si noti che vengono aggiornati solo i dati della sessione per l'applicazione corrente che corrispondono al valore SessionID fornito e i valori relativi all'identificatore di blocco. Dopo che il metodo SetAndReleaseItemExclusive è stato chiamato, il metodo ResetItemTimeout viene chiamato dall'istanza SessionStateModule per aggiornare la data e l'ora di scadenza dei dati relativi alla sessione. |
Metodo ReleaseItemExclusive |
Accetta come input l'istanza HttpContext per la richiesta corrente, il valore SessionID per la richiesta corrente e l'identificatore di blocco per la richiesta corrente, quindi rimuove il blocco da un elemento nell'archivio dati della sessione. Questo metodo viene chiamato quando viene chiamato il metodo GetItem o GetItemExclusive e l'archivio dati specifica che l'elemento richiesto è bloccato, ma l'intervallo di blocco ha superato il valore ExecutionTimeout. Il blocco viene rimosso da questo metodo e l'elemento può quindi essere utilizzato da altre richieste. |
Metodo RemoveItem |
Accetta come input l'istanza HttpContext per la richiesta corrente, il valore SessionID per la richiesta corrente e l'identificatore di blocco per la richiesta corrente. Elimina le informazioni sulla sessione dall'archivio dati nel caso in cui l'elemento nell'archivio corrisponde al valore SessionID fornito, all'applicazione corrente e all'identificatore di blocco fornito. Questo metodo viene chiamato quando viene chiamato il metodo Abandon. |
Metodo CreateUninitializedItem |
Accetta come input l'istanza HttpContext per la richiesta corrente, il valore SessionID per la richiesta corrente e l'identificatore di blocco per la richiesta corrente. Aggiunge quindi un elemento non inizializzato nell'archivio dati della sessione con un valore actionFlags pari a InitializeItem. Il metodo CreateUninitializedItem viene utilizzato con le sessioni senza cookie quando l'attributo regenerateExpiredSessionId è impostato su true. In questo caso, quando viene rilevato un ID di sessione scaduto, l'istanza SessionStateModule genera un nuovo valore SessionID. Il processo di generazione di un nuovo valore SessionID richiede che il browser venga reindirizzato su un URL che contiene l'ID di sessione appena generato. Il metodo CreateUninitializedItem viene chiamato durante una richiesta iniziale che contiene un ID di sessione scaduto. Non appena acquisisce un nuovo valore SessionID da sostituire all'ID di sessione scaduto, l'istanza SessionStateModule chiama il metodo CreateUninitializedItem per aggiungere una voce non inizializzata all'archivio dati dello stato sessione. Il browser viene quindi reindirizzato sull'URL contenente il nuovo valore SessionID generato. L'esistenza della voce non inizializzata nell'archivio dati della sessione assicura che la richiesta reindirizzata con il nuovo valore SessionID generato non venga scambiata per una richiesta di sessione scaduta e venga invece trattata come una nuova sessione. La voce non inizializzata nell'archivio dati della sessione viene associata al nuovo valore SessionID generato e contiene solo valori predefiniti, incluse la data e l'ora di scadenza e un valore che corrisponde al parametro actionFlags dei metodi GetItem e GetItemExclusive. La voce non inizializzata nell'archivio dati dello stato sessione deve includere un valore actionFlags uguale al valore di enumerazione InitializeItem (1). Questo valore viene passato all'istanza SessionStateModule dai metodi GetItem e GetItemExclusive e specifica all'istanza SessionStateModule che la sessione corrente è una nuova sessione. L'istanza SessionStateModule inizializzerà quindi la nuova sessione e genererà l'evento Session_OnStart. |
Metodo CreateNewStoreData |
Accetta come input l'istanza HttpContext per la richiesta corrente e il valore Timeout per la sessione corrente, quindi restituisce un nuovo oggetto SessionStateStoreData con un oggetto ISessionStateItemCollection vuoto, un insieme HttpStaticObjectsCollection e il valore Timeout specificato. L'istanza HttpStaticObjectsCollection per l'applicazione ASP.NET può essere recuperata utilizzando il metodo GetSessionStaticObjects. |
Metodo SetItemExpireCallback |
Accetta come input un delegato che fa riferimento all'evento Session_OnEnd definito nel file Global.asax. Se il provider dell'archivio dello stato sessione supporta l'evento Session_OnEnd, viene impostato un riferimento locale al parametro SessionStateItemExpireCallback e il metodo restituisce true. In caso contrario, il metodo restituisce un valore false. |
Provider di esempio
Per visualizzare un esempio di implementazione di un provider dell'archivio dello stato sessione personalizzato che gestisce le informazioni sulla sessione in un database Access, vedere Provider dell'archivio dello stato sessione di esempio.
Vedere anche
Concetti
Provider dell'archivio dello stato sessione di esempio