État de session
ASP.NET fournit l'infrastructure des informations d'état entre les demandes (paniers électroniques, défilement de données, etc.) dont les applications Web ont besoin, avec la fonctionnalité d'état de session intégrée qui vous permet de prendre les mesures suivantes :
Identifier et classer automatiquement les demandes provenant d'un client navigateur unique dans une session d'application logique sur le serveur.
Stocker les données à portée de session sur le serveur pour qu'elles soient utilisées sur plusieurs demandes de navigateur.
Déclencher les événements appropriés de gestion du cycle de vie d'une session (Session_OnStart, Session_OnEnd, etc.) qui peuvent être gérés dans le code de l'application.
Remarque L'événement Session_OnEnd n'est pris en charge que dans le mode d'état de session in-process. L'événement n'est pas déclenché si vous utilisez les modes serveur d'état ou SQL Server.
Libérer automatiquement les données de session si le navigateur ne revisite pas une application au cours d'une période donnée.
Cette rubrique fournit une vue d'ensemble de l'état de session, décrit la façon dont les sessions ASP.NET actives sont identifiées et suivies, explique le magasin d'état de session et la structure générale et conclut sur un exemple de code de niveau élevé.
Vue d'ensemble de l'état de session
HTTP est un protocole sans état, ce qui signifie qu'il n'indique pas automatiquement si une séquence de demandes provient entièrement du même client ni même si une instance d'un navigateur unique affiche toujours activement une page ou un site. Par conséquent, le développement d'applications Web qui doivent conserver les informations d'état entre les demandes (paniers électroniques, défilement de données, etc.) peut se révéler extrêmement complexe sans l'aide d'une infrastructure supplémentaire.
ASP.NET fournit la prise en charge suivante pour les sessions :
- Fonctionnalité d'état de session facile à utiliser, connue des développeurs ASP et cohérente par rapport aux autres API .NET Framework.
- Fonctionnalité d'état de session fiable qui peut survivre aux redémarrages des services IIS (Internet Information Services) et du processus de travail sans perte de données de session.
- Fonctionnalité d'état de session évolutive qui peut être utilisée à la fois dans les scénarios de batterie de serveurs Web (plusieurs ordinateurs) et de jardin Web (plusieurs processus) et qui permet aux administrateurs d'allouer plus de processeurs à une application Web pour en améliorer l'évolutivité.
- Fonctionnalité d'état de session qui fonctionne avec les navigateurs qui ne prennent pas en charge les cookies HTTP.
- Débit équivalent (ou supérieur) à celui d'ASP pour les principaux scénarios d'état de session (lecture/écriture 50/50 lorsque les éléments sont placés dans les paniers, la dernière page visitée est modifiée, les informations de carte de crédit sont validées, etc.).
Toutefois, l'état de session ne persiste pas entre les limites d'application Web. Si une application Web bascule vers une autre application durant l'exécution, les informations de session ne sont pas disponibles pour la nouvelle application.
Identification d'une session
Chaque session ASP.NET active est identifiée et suivie à l'aide d'une chaîne SessionID 120 bits contenant uniquement les caractères ASCII autorisés dans les URL. Les valeurs SessionID sont générées à l'aide d'un algorithme qui en garantit le caractère unique de sorte que les sessions n'entrent pas en conflit et le caractère aléatoire de sorte qu'un utilisateur malveillant ne puisse pas utiliser un nouveau SessionID pour calculer le SessionID d'une session existante.
Les chaînes SessionID sont communiquées sur les demandes client-serveur au moyen d'un cookie HTTP ou d'une URL modifiée avec la chaîne SessionID incorporée, selon la configuration des paramètres de l'application.
Magasin d'état de session
ASP.NET fournit un modèle d'état de session simple et facile à utiliser pour stocker des données et des objets arbitraires sur plusieurs demandes Web. Il utilise pour cela un cache en mémoire basé sur un dictionnaire de références d'objets qui vivent dans le processus IIS. Lorsque vous utilisez le mode d'état de session in-process, tenez compte des restrictions suivantes :
- Lorsque vous utilisez le mode d'état de session in-process, les données d'état de session sont perdues en cas de redémarrage de aspnet_wp.exe ou du domaine de l'application. Ces redémarrages se produisent généralement dans les circonstances suivantes :
- La définition d'un attribut dans l'élément <processModel> du fichier Web.config de l'application déclenche le démarrage d'un nouveau processus lorsqu'une condition, telle que memoryLimit, est remplie.
- Le fichier Global.asax ou Web.config est modifié.
- Le répertoire \Bin de l'application Web devient le répertoire actif.
- Le logiciel antivirus analyse et modifie le fichier Global.asax, Web.config ou encore un fichier du répertoire \Bin de l'application Web.
- Si vous activez le mode jardin Web dans l'élément <processModel> du fichier Web.config de l'application, n'utilisez pas le mode d'état de session in-process. Sinon, des pertes de données aléatoires peuvent se produire.
Au lieu de conserver des objets vivants, le serveur d'état .NET stocke simplement l'état de session en mémoire en mode out-of-process. Dans ce mode, le processus de travail parle directement au serveur d'état. En mode SQL, les états de session sont stockés dans une base de données SQL Server et le processus de travail parle directement à SQL. Les processus de travail ASP.NET sont alors capables de tirer parti de ce simple service de stockage en sérialisant et en enregistrant (à l'aide des services de sérialisation .NET) tous les objets dans une collection Session d'un client à la fin de chaque demande Web. Lorsque le client revisite le serveur, le processus de travail ASP.NET concerné extrait ces objets du serveur d'état comme flux binaires, les désérialise dans des instances vivantes et les replace dans un nouvel objet de la collection Session exposé au gestionnaire de demandes.
En mode SQL, l'état de session peut également être configuré pour opérer dans un cluster de basculement. Un cluster de basculement est constitué d'un ou de deux serveurs Web identiques redondants qui stockent leurs données de session sur un ordinateur distinct, dans une base de données SQL Server. Pour plus d'informations sur cette configuration, consultez Configuration du mode SQL Server.
En séparant clairement le stockage des données de session de leur utilisation par l'application, ASP.NET prend en charge plusieurs scénarios puissants, qui n'étaient pas disponibles avec les versions antérieures d'ASP :
Restauration suite aux pannes de l'application car la mémoire utilisée pour l'état de session ne se trouve pas dans le processus de travail ASP.NET.
Puisque tout l'état est stocké à part d'un processus de travail individuel, il n'est pas perdu si le processus tombe en panne en raison d'une violation d'accès ou si le service d'administration IIS le force à redémarrer en cas de blocage ou de fuite de mémoire.
Partitionnement d'une application sur plusieurs processus de travail.
Étant donné que tout l'état est stocké à part des processus de travail, vous pouvez clairement partitionner une application sur plusieurs processus. Ce partitionnement peut considérablement améliorer la disponibilité et l'évolutivité d'une application sur des ordinateurs à processus multiples. De plus, puisqu'il associe chaque processus de travail à un ordinateur unique, ASP.NET est capable d'éliminer la charge de verrouillage interprocesseurs, l'un des principaux goulets d'étranglement de l'évolutivité dans les versions antérieures d'ASP.
Partitionnement d'une application sur plusieurs ordinateurs d'une batterie de serveurs Web.
Étant donné que tout l'état est stocké à part des processus de travail, vous pouvez partitionner une application sur plusieurs processus de travail s'exécutant sur plusieurs ordinateurs. Le modèle de communication d'un état entre un processus de travail et un service d'état s'exécutant sur des ordinateurs différents est presque le même que celui pour les processus et les serveurs s'exécutant sur le même ordinateur. Dans les deux cas, il ne peut y avoir qu'un seul serveur d'état par batterie de serveurs Web.
Structure d'état de session
Les applications ASP.NET utilisent une organisation d'exécution basée sur les événements pour permettre à plusieurs modules de classe .NET Framework de participer au traitement d'une demande Web unique.
Module SessionState
Le .NET Framework implémente l'état de session par l'intermédiaire de la classe SessionStateModule (dérivée de IHttpModule), qui participe à l'exécution de chaque demande reçue par une application .NET. SessionStateModule est chargé de générer ou d'obtenir des chaînes SessionID uniques et de stocker et d'extraire des données d'état à partir d'un fournisseur d'état externe.
Collections d'état de session
La classe SessionState expose deux collections d'état : Contents et StaticObjects. La collection Contents expose tous les éléments de variable ajoutés à la collection d'état de session directement par l'intermédiaire du code. Par exemple :
' 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;
Pour des raisons de compatibilité avec les versions antérieures de ASP, ces valeurs sont aussi accessibles par l'intermédiaire d'une propriété Contents sur l'objet de l'application, comme dans l'exemple suivant.
' 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;
La collection StaticObjects expose tous les éléments de variable ajoutés à la collection de l'état de session par l'intermédiaire des balises <object runat="server"> avec la portée de Session dans le fichier Global.asax. Par exemple :
' Global.asax definition.
<OBJECT RUNAT="SERVER" SCOPE="SESSION" ID="MyInfo" PROGID="Scripting.Dictionary">
</OBJECT>
Les objets ne peuvent pas être ajoutés à la collection StaticObjects à partir de n'importe quel emplacement d'une application ASP.NET. La collection lève NotSupportedException si les utilisateurs tentent d'ajouter des objets directement par l'intermédiaire du code.
Remarque Le compilateur de pages ASP.NET injecte automatiquement des références à des membres dans tous les objets stockés dans la collection StaticObjects au moment de la compilation de la page.
Les développeurs de pages peuvent accéder aux objets Session directement au moment de la demande de la page sans avoir à traverser la collection StaticObjects, comme le montre l'exemple suivant :
<html>
</body>
Number of entries: <%= MyInfo.Count %>
<body>
</html>
Configuration et démarrage de l'état de session
Il existe trois modes d'état de session dans ASP.NET. Vous pouvez choisir entre in-process, serveur d'état et SQL Server. Quel que soit le mode choisi, le processus de configuration de base reste le même.
ASP.NET configure l'état de session en deux étapes. Le module d'état de session est d'abord inséré dans la demande HTTP. Ceci est effectué par défaut au niveau de la racine de la hiérarchie de configuration dans le fichier Machine.config à l'échelle de l'ordinateur.
L'exemple suivant montre un exemple d'entrée dans le fichier Machine.config. Pour que le fichier de configuration fonctionne correctement, vous devez fournir le nom qualifié complet d'assembly pour la version appropriée de l'assembly System.Web.SessionState.SessionStateModule. Cette version est généralement celle qui est associée à la version du .NET Framework utilisée par votre application. Pour plus d'informations sur l'obtention du nom qualifié complet d'assembly, consultez Noms d'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>
Ensuite, en fonction du mode d'état de session que vous souhaitez utiliser, définissez les attributs de service d'état de session appropriés dans l'élément de configuration <sessionState>.
Configuration du mode in-process
In-process est le mode d'état de session par défaut. Pour utiliser ce mode, affectez la valeur Inproc à l'attribut mode de l'élément <sessionState>.
Voici un exemple de configuration du mode in-process.
<configuration>
<system.web>
<sessionState mode="Inproc"
cookieless="false"
timeout="20"/>
</sessionState>
</system.web>
</configuration>
Configuration du mode serveur d'état
Pour utiliser le serveur d'état, vous devez d'abord vérifier que le service d'état ASP.NET est en cours d'exécution sur le serveur distant utilisé pour le magasin de session. Ce service est installé avec ASP.NET et Visual Studio .NET à l'emplacement suivant :
systemroot\Microsoft.NET\Framework\Numéroversion\aspnet_state.exe
Affectez ensuite à l'attribut mode de l'élément <sessionState> la valeur StateServer dans le fichier Web.config de l'application. Enfin, affectez à l'attribut connectionString la valeur **tcpip=Nomserveur:**Numéroport.
Voici un exemple de configuration du mode serveur d'état.
<configuration>
<system.web>
<sessionState mode="StateServer"
stateConnectionString="tcpip=dataserver:42424"
cookieless="false"
timeout="20"/>
</sessionState>
</system.web>
</configuration>
Configuration du mode SQL Server
Pour utiliser SQL Server, exécutez d'abord InstallSqlState.sql ou InstallPersistSqlState.sql sur l'ordinateur avec SQL Server qui va stocker l'état de session. L'un et l'autre scripts créent une base de données appelée ASPState qui inclut plusieurs procédures stockées. La différence entre ces deux scripts est l'emplacement des tables ASPStateTempApplications et ASPStateTempSessions. Le script InstallSqlState.sql ajoute ces tables à la base de données TempDB qui perd les données de session en cas de redémarrage de l'ordinateur. Le script InstallPersistSqlState.sql ajoute ces tables à la base de données ASPState qui permet de conserver les données de session en cas de redémarrage de l'ordinateur.
Ces deux fichiers de script sont installés par défaut à l'emplacement suivant :
systemroot\Microsoft.NET\Framework\Numéroversion
Affectez ensuite à l'attribut mode de l'élément <sessionState> la valeur SQLServer dans le fichier Web.config de l'application. Enfin, affectez à l'attribut sqlConnectionString la valeur Integrated Security=SSPI;data source=Nomserveur;.
Voici un exemple de configuration du mode SQL Server.
<configuration>
<system.web>
<sessionState mode="SQLServer"
sqlConnectionString=" Integrated Security=SSPI;data source=dataserver;"
cookieless="false"
timeout="20"/>
</sessionState>
</system.web>
</configuration>
En mode SQL Server, l'état de session peut également être configuré pour opérer dans un cluster de basculement. Un cluster de basculement est constitué d'un ou de deux serveurs Web identiques redondants qui stockent leurs données de session sur un ordinateur distinct, dans une base de données SQL Server. Si un serveur Web tombe en panne, un autre serveur du cluster le relaie et répond aux demandes sans pertes des données de session. Pour configurer un cluster de basculement, définissez l'élément <machinekey> du fichier Web.config des serveurs Web avec la même valeur. Définissez ensuite la chaîne de connexion SQL des serveurs Web pour qu'elle pointe vers la base de données SQL Server sur l'ordinateur qui stocke les données de session.
Exemple de code de niveau élevé
L'exemple suivant illustre comment accéder à des données d'état de session existantes en lecture seule pour générer de manière dynamique une page contenant des informations utilisateur et des informations personnelles relatives au portefeuille d'actions.
<%@ 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>