Stato della sessione

In ASP.NET è disponibile l'infrastruttura di informazioni sullo stato per richieste incrociate (carrelli delle spese, scorrimento dati e così via) necessaria per le applicazioni Web, con la funzionalità di stato della sessione incorporata che consente di effettuare le seguenti operazioni:

  • Identificare e classificare automaticamente le richieste provenienti da un singolo client browser in una sessione logica dell'applicazione sul server.

  • Archiviare i dati con ambito di sessione sul server in modo da consentirne l'utilizzo per più richieste del browser.

  • Generare eventi appropriati di gestione della durata della sessione (Session_OnStart, Session_OnEnd e così via) che possano essere gestiti nel codice dell'applicazione.

    Nota   L'evento Session_OnEnd è supportato solo nella modalità in-process dello stato della sessione. Se si utilizza la modalità server di stato o SQL Server, questo evento non viene generato.

  • Rilasciare automaticamente i dati della sessione se il browser non invia richieste a un'applicazione entro un determinato periodo di timeout.

In questo argomento viene fornita una panoramica sullo stato della sessione, sulle modalità di identificazione e analisi delle sessioni ASP.NET attive e sull'archivio e la struttura generale dello stato della sessione. Al termine, viene anche fornito un esempio di codice di alto livello.

Cenni preliminari sullo stato della sessione

HTTP è un protocollo senza informazioni sullo stato, ovvero che non indica automaticamente se una sequenza di richieste proviene dallo stesso client o se una singola istanza del browser sta ancora visualizzando attivamente una pagina o un sito. Di conseguenza la generazione di applicazioni Web per le quali è necessario conservare informazioni sullo stato per le richieste incrociate (carrelli delle spese, scorrimento dati e così via) può risultare estremamente difficile senza il supporto di un'infrastruttura aggiuntiva.

In ASP.NET è disponibile il supporto seguente per le sessioni:

  • Una funzionalità di stato della sessione di facile utilizzo, nota agli sviluppatori ASP e coerente con le altre API di .NET Framework.
  • Una funzionalità di stato della sessione affidabile e in grado di superare i riavvii di IIS (Internet Information Services) e dei processi di lavoro senza generare alcuna perdita dei dati della sessione.
  • Una funzionalità scalabile di stato della sessione che può essere utilizzata sia in scenari Web farm (più computer) che Web garden (più processi) e che consente agli amministratori di allocare più processori a un'applicazione Web per migliorarne la scalabilità.
  • Una funzionalità di stato della sessione che utilizza browser che non supportano cookie HTTP.
  • Una velocità di trasmissione dei dati equivalente a quella di ASP o persino maggiore per gli scenari principali relativi allo stato della sessione (lettura/scrittura 50/50 per l'inserimento di oggetti nei carrelli delle spese, la modifica dell'ultima pagina visitata, la convalida dei dati relativi alle carte di credito e così via).

Lo stato della sessione, comunque, non persiste oltre i limiti dell'applicazione Web. Se durante l'esecuzione avviene un passaggio da un'applicazione Web a un'altra, la nuova applicazione non disporrà delle informazioni sulla sessione della prima applicazione.

Identificazione di una sessione

Per identificare e tenere traccia di ogni sessione ASP.NET attiva viene utilizzata una stringa SessionID a 120 bit contenente solo i caratteri ASCII consentiti negli URL. I valori SessionID vengono generati tramite un algoritmo che ne garantisce l'univocità per evitare conflitti di sessione, nonché la casualità in modo che un utente non autorizzato non possa utilizzare un nuova stringa SessionID per calcolare il valore SessionID di una sessione esistente.

Le stringhe SessionID vengono comunicate attraverso richieste client/server mediante un cookie HTTP o un URL modificato con la stringa SessionID incorporata, in base alla configurazione delle impostazioni dell'applicazione.

Archiviazione dello stato della sessione

In ASP.NET è disponibile un modello di stato della sessione semplice e di facile utilizzo che consente di archiviare dati e oggetti arbitrari tra più richieste Web. Tale operazione viene eseguita tramite una cache in memoria, basata su un dizionario e contenente riferimenti a oggetti che risiedono nel processo IIS. Quando si utilizza la modalità in-process dello stato della sessione, occorrerà considerare le seguenti limitazioni:

  • Quando si utilizza la modalità in-process dello stato della sessione, i dati dello stato della sessione andranno persi se viene riavviato aspnet_wp.exe o il dominio dell'applicazione. Tali riavvii hanno solitamente luogo nei seguenti casi:
    • Quando si imposta un attributo nell'elemento <processModel> del file Web.config dell'applicazione che comporta l'avvio di un nuovo processo quando viene soddisfatta una condizione, quale ad esempio memoryLimit.
    • Quando si modifica il file Global.asax o Web.config.
    • Quando si apportano modifiche alla directory \Bin dell'applicazione Web.
    • Quando un software antivirus durante la scansione modifica il file Global.asax, il file Web.config o un file nella directory \Bin dell'applicazione Web.    
  • Se si attiva la modalità scenario Web nell'elemento <processModel> del file Web.config dell'applicazione, non utilizzare la modalità in-process dello stato della sessione. In caso contrario, vi potrà essere una perdita casuale di dati.

Anziché mantenere gli oggetti attivi, in modalità out-of-process il server di stato .NET archivia semplicemente lo stato della sessione in memoria. In questa modalità il processo di lavoro comunica direttamente con il server di stato. Nella modalità SQL gli stati delle sessioni sono archiviati in un database SQL Server e il processo di lavoro comunica direttamente con SQL. I processi di lavoro ASP.NET usufruiscono quindi di questo semplice servizio di archiviazione serializzando e salvando, tramite servizi di serializzazione .NET, tutti gli oggetti di un insieme Session del client al termine di ogni richiesta Web. Quando il client effettua nuovamente richieste al server, il processo di lavoro ASP.NET corrispondente recupera questi oggetti dal server di stato come flussi binari, li deserializza in istanze attive e li reinserisce in un nuovo oggetto dell'insieme Session esposto al gestore delle richieste.

In modalità SQL, lo stato della sessione può anche essere configurato in modo da funzionare in un cluster di failover. Un cluster di failover è costituito da due o più server Web ridondanti identici che memorizzano i propri dati di sessione su un computer diverso in un database SQL Server. Per ulteriori informazioni su come impostare questa configurazione, vedere Configurazione della modalità SQL Server.

La separazione netta dell'archiviazione dei dati di sessione dal relativo utilizzo tramite l'applicazione consente a ASP.NET di supportare diversi scenari efficaci che non erano disponibili nelle versioni precedenti di ASP:

  • Recupero dai blocchi dell'applicazione, in quanto la memoria utilizzata per lo stato della sessione non è all'interno del processo di lavoro ASP.NET.

    Poiché viene archiviato separatamente dai singoli processi di lavoro, lo stato non viene perduto se il processo si blocca a causa di una violazione di accesso o è riavviato forzatamente da IIS Admin Service nel caso di un blocco critico o di perdite di memoria.

  • Partizionamento di un'applicazione in più processi di lavoro.

    Poiché tutto lo stato viene archiviato separatamente dai processi di lavoro, è possibile partizionare un'applicazione in più processi. Tale operazione consente di migliorare notevolmente la disponibilità e la scalabilità di un'applicazione sui computer con più processi. Inoltre, poiché ogni processo di lavoro viene associato a un singolo computer, ASP.NET consente di eliminare i conflitti di blocco tra più processori, che rappresentava una delle problematiche relative alla scalabilità di più difficile soluzione nelle versioni precedenti di ASP.

  • Partizionamento di un'applicazione in più computer Web farm.

    Poiché lo stato completo viene archiviato separatamente dai processi di lavoro, è possibile partizionare un'applicazione in più processi di lavoro in esecuzione su più computer. Il modello per la comunicazione dello stato tra un processo di lavoro e un servizio di stato in esecuzione su più computer è quasi identico a quello per i processi e i server in esecuzione sullo stesso computer. In entrambi i casi è possibile utilizzare un solo server di stato per ogni Web farm.

Struttura dello stato della sessione

Nelle applicazioni basate su ASP.NET viene utilizzata un'organizzazione dell'esecuzione basata sugli eventi per consentire a più moduli di classe .NET Framework di contribuire all'elaborazione di ogni singola richiesta Web.

Modulo SessionState

.NET Framework implementa lo stato della sessione tramite la classe SessionStateModule derivata da IHttpModule, che contribuisce all'esecuzione di ogni richiesta proveniente da un'applicazione basata su .NET. La classe SessionStateModule è preposta alla generazione e al recupero di stringhe SessionID univoche, nonché all'archiviazione e al recupero di dati relativi allo stato da un provider di stato esterno.

Insiemi dello stato della sessione

La classe SessionState espone due insiemi di stato: Contents e StaticObjects. L'insieme Contents espone tutti gli elementi delle variabili che sono stati aggiunti all'insieme dello stato della sessione direttamente tramite codice. Esempio:

' Visual Basic code from within a page, a handler, or Global.asax.
Session("Message") = "MyMsg"
Session("AppStartTime") = Now
[C#]
// C# code from within a page, a handler, or Global.asax.
Session["Message"] = "MyMsg";
Session["AppStartTime"] = DateTime.Now;

Per compatibilità con le versioni precedenti di ASP, è anche possibile accedere a questi valori utilizzando la proprietà Contents dell'oggetto applicazione, come mostrato nell'esempio che segue.

' Visual Basic code from within a page, a handler, or Global.asax.
Session.Contents("Message") = "MyMsg"
Session.Contents("AppStartTime") = Now
[C#]
// C# code from within a page, a handler, or Global.asax.
Session.Contents["Message"] = "MyMsg";
Session.Contents["AppStartTime"] = DateTime.Now;

L'insieme StaticObjects espone tutti gli elementi delle variabili che sono stati aggiunti all'insieme dello stato della sessione tramite i tag <object runat="server"> con l'ambito "Session" del file Global.asax. Esempio:

' Global.asax definition.
<OBJECT RUNAT="SERVER" SCOPE="SESSION" ID="MyInfo" PROGID="Scripting.Dictionary">
</OBJECT>

Gli oggetti non possono essere aggiunti all'insieme StaticObjects da un punto qualsiasi di un'applicazione ASP.NET. Se si cerca di aggiungere oggetti direttamente tramite codice, l'insieme genera un'eccezione NotSupportedException.

Nota   Il compilatore di pagine ASP.NET inserisce automaticamente i riferimenti ai membri in tutti gli oggetti archiviati nell'insieme StaticObjects durante la fase di compilazione delle pagine.

Gli sviluppatori delle pagine possono accedere agli oggetti Session durante la richiesta delle pagine senza dover scorrere l'insieme StaticObjects, come nell'esempio seguente:

<html>
   </body>
      Number of entries: <%= MyInfo.Count %>
   <body>
</html>

Configurazione e avvio dello stato della sessione

In ASP.NET vi sono tre modalità di stato della sessione: in-process, server di stato e SQL Server. Il processo di configurazione di base è lo stesso, indipendentemente dalla modalità scelta.

ASP.NET consente di configurare lo stato della sessione in due fasi. Il modulo dello stato della sessione viene inserito innanzitutto nella richiesta HTTP. Per impostazione predefinita, tale operazione viene eseguita nella radice della gerarchia di configurazione nel file di sistema Machine.config.

Nel codice che segue viene mostrato un elemento di esempio nel file Machine.config. Ai fini del corretto funzionamento del file di configurazione, è necessario fornire il nome completo della versione appropriata dell'assembly System.Web.SessionState.SessionStateModule. Tale versione è solitamente quella associata alla versione di .NET Framework utilizzata dall'applicazione. Per ulteriori informazioni su come ottenere il nome completo dell'assembly, vedere Nomi degli assembly.

<httpmodules>
   ...
    <!-- You must supply a valid fully qualified assembly name here. -->
    <!-- For this example to work correctly, the version number for -->
    <!-- the referenced assemby must match the version installed on -->
    <!-- your computer by the .NET Framework. -->
    <add name="sessionState" type="System.Web.SessionState.SessionStateModule, Version=1.0.3300.0,Culture=neutral,PublicKeyToken=b77a5c561934e089" />
   ...
</httpmodules>

A seconda della modalità di stato della sessione che si desidera utilizzare, impostare infine i relativi attributi del servizio di stato della sessione nell'elemento di configurazione <sessionState>.

Configurazione della modalità in-process

In-process è la modalità predefinita di stato della sessione. Per utilizzare la modalità in-process, impostare l'attributo mode dell'elemento <sessionState> su Inproc.

Nel codice che segue viene mostrato un esempio di impostazioni per la configurazione della modalità in-process.

<configuration>
    <system.web>
        <sessionState mode="Inproc"
                      cookieless="false"
                      timeout="20"/>
        </sessionState>
    </system.web>
</configuration>

Configurazione della modalità server di stato

Per utilizzare il server di stato, è necessario assicurarsi che il servizio di stato ASP.NET sia in esecuzione sul server remoto utilizzato per archiviare la sessione. Questo servizio viene installato con ASP.NET e Visual Studio .NET nel seguente percorso:

directory_di_sistema\Microsoft.NET\Framework\numero_versione\aspnet_state.exe

Impostare quindi l'attributo mode dell'elemento <sessionState> su StateServer nel file Web.config dell'applicazione. Impostare infine l'attributo connectionString su **tcpip=serverName:**portNumber.

Nel codice che segue viene mostrato un esempio di impostazioni per la configurazione della modalità server di stato.

<configuration>
    <system.web>
        <sessionState mode="StateServer"
                      stateConnectionString="tcpip=dataserver:42424"
                      cookieless="false"
                      timeout="20"/>
        </sessionState>
    </system.web>
</configuration>

Configurazione della modalità SQL Server

Per utilizzare SQL Server, eseguire in primo luogo InstallSqlState.sql o InstallPersistSqlState.sql sul computer in cui è presente SQL Server, nel quale verrà memorizzato lo stato della sessione. Con entrambi gli script viene creato un database denominato ASPState che include diverse stored procedure. La differenza tra i due script sta nel luogo in cui vengono poste le tabelle ASPStateTempApplications e ASPStateTempSessions. Lo script InstallSqlState.sql aggiunge le tabelle al database TempDB, che in caso di riavvio del computer perde i dati della sessione. Lo script InstallPersistSqlState.sql script aggiunge invece le tabelle al database ASPState, che conserva i dati della sessione anche in caso di riavvio del computer.

Il percorso di installazione predefinito di entrambi gli script è:

directory_di_sistema\Microsoft.NET\Framework\numero_versione

Impostare quindi l'attributo mode dell'elemento <sessionState> su SQLServer nel file Web.config dell'applicazione. Impostare infine l'attributo sqlConnectionString su Integrated Security=SSPI;data source=serverName;.

Nel codice che segue viene mostrato un esempio di impostazioni per la configurazione della modalità SQL Server.

<configuration>
    <system.web>
        <sessionState mode="SQLServer"
                      sqlConnectionString=" Integrated Security=SSPI;data source=dataserver;"
                      cookieless="false"
                      timeout="20"/>
        </sessionState>
    </system.web>
</configuration>

In modalità SQL Server, lo stato della sessione può anche essere configurato in modo da funzionare in un cluster di failover. Un cluster di failover è costituito da due o più server Web ridondanti identici che memorizzano i propri dati di sessione su un computer diverso in un database SQL Server. Se si verifica un errore in un server Web, il ruolo di tale server verrà assunto da un altro server del cluster che si farà carico delle richieste senza alcuna perdita dei dati della sessione. Per configurare un cluster di failover, impostare l'elemento <machinekey> nel file Web.config dei server Web sullo stesso valore. Impostare quindi la stringa di connessione SQL dei server Web in modo che punti al database SQL Server del computer in cui vengono archiviati i dati della sessione.

Esempio di codice di alto livello

Nell'esempio che segue viene descritto come accedere ai dati esistenti relativi allo stato della sessione in modalità di sola lettura per generare dinamicamente una pagina contenente informazioni sull'utente e sul portafoglio di azioni personale.

<%@ Language=VB EnableSessionState=true %>
<html>
   <head>
      <script runat="server">
         Sub Page_Load(ByVal Sender as Object, ByVal E as EventArgs)
              ' Obtain data table of user's personal stock data.
              Dim MyStocks as DataTable
              Dim Stock as DataRow
              MyStocks = _
                 CType(Session("PersonalStockData"), DataTable)
              ' Update HTML output with session values.
              Name.InnerText = Session("FirstName").ToString()
              SpouseVal.InnerText = Session("SpouseName").ToString()
              For Each Stock In MyStocks.Rows
                 StockList.AddItem(Stock("Symbol") & ": " & Stock("Name"))
              Next
         End Sub
      </script>
   </head>
   <body>
      Hi <span id="Name" runat=server/>, your spouse is: <span id="SpouseVal" runat="server"/>.
      Here are the stocks you and your spouse currently own:
      <acme:listbox id="StockList" runat="server">
         <! — List box is dynamically populated from code. -->
      </acme:listbox>
   </body>
</html>
[C#]
<%@ Language=C# EnableSessionState=true %>
<html>
   <head>
      <script runat=server>
         void Page_Load(Object Sender, EventArgs E) {
              // Obtain data table of user's personal stock data.
              DataTable MyStocks =
                 (DataTable)Session["PersonalStockData"];
              // Update HTML output with session values.
              Name.InnerText = Session["FirstName"].ToString();
              SpouseVal.InnerText = Session["SpouseName"].ToString();
              foreach (DataRow Stock in MyStocks.Rows) {
                 StockList.AddItem(Stock["Symbol"] + ": "
                                 + Stock["Name"]);
              }
         }
      </script>
   </head>
   <body>
      Hi <span id="Name" runat="server"/>, your spouse is: <span id="SpouseVal" runat="server"/>.
      Here are the stocks you and your spouse currently own:
      <acme:listbox id="StockList" runat="server">
         <! — List box is dynamically populated from code. -->
      </acme:listbox>
   </body>
</html>

Vedere anche

Gestione dello stato di ASP.NET