Implémentation d'un fournisseur de magasins d'état de session

Mise à jour : novembre 2007

Décrit une implémentation de fournisseur de magasins d'état de session personnalisée et explique comment implémenter un exemple de fournisseur.

L'état de session ASP.NET est conçu pour permettre le stockage des données de session utilisateur dans différentes sources. Par défaut, les valeurs et les informations d'état de session sont stockées dans la mémoire au sein du processus ASP.NET. Vous pouvez aussi stocker les données de session sur un serveur d'état qui garde les données de session dans un processus séparé et les conserve si l'application ASP.NET est arrêtée et redémarrée. Il existe une autre solution qui consiste à stocker les données de session dans une base de données SQL Server où elles peuvent être partagées par plusieurs serveurs Web.

Vous pouvez utiliser les magasins d'état de session qui sont inclus dans ASP.NET, ou vous pouvez implémenter votre propre fournisseur de magasins d'état de session. Vous pouvez créer un fournisseur de magasins d'état de session personnalisé pour les raisons suivantes :

  • Vous devez stocker des informations d'état de session dans une source de données autre que SQL Server, par exemple une base de données FoxPro ou Oracle.

  • Vous devez gérer des informations d'état de session à l'aide d'un schéma de base de données qui est différent de celui qui est utilisé par les fournisseurs fournis avec .NET Framework. Citons comme exemple des données de panier d'achat qui sont stockées avec un schéma prédéfini dans une base de données SQL Server existante.

Vous pouvez implémenter un fournisseur de magasins d'état de session personnalisé en créant une classe qui hérite la classe SessionStateStoreProviderBase. Pour plus d'informations, consultez la section « Classes requises » plus loin dans cette rubrique.

Module d'état de session

L'état de session est géré par la classe SessionStateModule qui appelle le fournisseur de magasins d'état de session pour lire les données de session et les écrire dans le magasin de données à différents moments pendant une demande. Au début d'une demande, l'instance de la SessionStateModule récupère les données de la source de données en appelant la méthode GetItemExclusive ou la méthode GetItem si la valeur ReadOnly a été affectée à l'attribut de page EnableSessionState. À la fin d'une demande, si les valeurs d'état de session ont été modifiées, l'instance de la SessionStateModule appelle la méthode SessionStateStoreProviderBase.SetAndReleaseItemExclusive pour écrire les valeurs mises à jour dans le magasin d'état de session. SessionStateModule appelle des membres supplémentaires de l'implémentation SessionStateStoreProviderBase pour initialiser une nouvelle session, mais aussi pour supprimer des données de session du magasin de données lorsque la méthode HttpSessionState.Abandon est appelée. Chaque membre de la classe SessionStateStoreProviderBase est décrit plus en détail à la section « Classes requises » plus loin dans cette rubrique.

La classe SessionStateModule détermine la valeur SessionID elle-même, plutôt que de compter sur le fournisseur de magasins d'état de session pour le faire. Si nécessaire, vous pouvez implémenter un SessionIDManager personnalisé en créant une classe qui hérite de l'interface ISessionIDManager. Pour plus d'informations, consultez la section « Notes » dans ISessionIDManager.

SessionStateModule reprendra l'identité du processus ASP.NET pour accéder à n'importe quelle ressource sécurisée, telle qu'un serveur de base de données. Vous pouvez spécifier que l'instance de la SessionStateModule emprunte l'identité fournie par IIS en affectant la valeur false à l'attribut useHostingIdentity de l'élément de configuration <sessionState>. Par exemple, si vous avez configuré votre application IIS pour l'utilisation de la sécurité intégrée de Windows et souhaitez qu'ASP.NET emprunte l'identité fournie par IIS pour la gestion de session, spécifiez <identity impersonate="true" /> dans la section de la configuration <system.web> du fichier Web.config de l'application et affectez la valeur false à l'attribut useHostingIdentity de l'élément de configuration <sessionState>. Si l'attribut useHostingIdentity a la valeur true, ASP.NET empruntera l'identité du processus ou les informations d'identification de l'utilisateur fournies à l'élément de configuration <identity> (si elles existent) lors de la connexion à la source de données. Pour plus d'informations sur l'identité du processus ASP.NET, consultez Configuration de l'identité de processus ASP.NET et Emprunt d'identité ASP.NET.

Verrouillage des données de magasin de session

Les applications ASP.NET sont multithread pour pouvoir répondre à plusieurs demandes simultanées. Plusieurs demandes simultanées peuvent essayer d'accéder aux mêmes informations sur les sessions. Considérez un scénario où plusieurs frames d'un jeu de frames font tous référence aux pages Web ASP.NET de la même application. Les demandes distinctes pour chaque frame du jeu de frames peuvent être exécutées simultanément sur le serveur Web sur différents threads. Si les pages ASP.NET de chaque frame accèdent aux variables de l'état de session, vous pouvez avoir plusieurs threads qui accèdent simultanément au magasin de session. Pour éviter des collisions de données dans le magasin de session et un comportement d'état de session inattendu, les classes SessionStateModule et SessionStateStoreProviderBase contiennent des fonctionnalités qui verrouillent de manière exclusive l'élément de magasin de session pour une session particulière pendant l'exécution d'une page ASP.NET. Notez qu'aucun verrouillage n'est défini sur un élément de magasin de session si l'attribut EnableSessionState est marqué comme étant ReadOnly. Toutefois, il est possible que d'autres pages ASP.NET de la même application écrivent dans le magasin de session et, par conséquent, qu'une demande de données de session en lecture seule du magasin soit obligée d'attendre la libération des données verrouillées.

Un verrouillage est défini sur les données de magasin de session au début de la demande dans l'appel à la méthode GetItemExclusive. Lorsque la demande se termine, le verrouillage est annulé pendant l'appel à la méthode SetAndReleaseItemExclusive.

Si l'instance de la SessionStateModule rencontre des données de session verrouillées pendant l'appel à la méthode GetItemExclusive ou GetItem, elle redemande les données de session à des intervalles d'une demi-seconde jusqu'à ce que le verrouillage soit supprimé ou que le délai spécifié dans la propriété ExecutionTimeout soit écoulé. Si le délai d'expiration d'exécution est dépassé, SessionStateModule appelle la méthode ReleaseItemExclusive pour libérer les données de magasin de session et demander les données de magasin de session à ce moment-là.

Les données de magasin de session verrouillées ont pu être libérées par un appel à la méthode ReleaseItemExclusive, sur un thread distinct, avant l'appel à la méthode SetAndReleaseItemExclusive pour la réponse actuelle. En conséquence, l'instance de la SessionStateModule peut définir et libérer des données de magasin d'état de session qui ont déjà été libérées et modifiées par une autre session. Pour éviter cette situation, l'instance de SessionStateModule inclut un identificateur de verrou dans chaque demande pour modifier les données de magasin de session verrouillées. Les données de magasin de session sont modifiées uniquement si l'identificateur de verrou dans le magasin de données correspond à l'identificateur de verrou fourni par SessionStateModule.

Suppression de données de magasin de session expirée

Lorsque la méthode Abandon est appelée pour une session, les données pour cette session sont supprimées du magasin de données à l'aide de la méthode RemoveItem. Sinon, les données restent dans le magasin de données de session pour servir à de futures demandes pour la session.

Le mécanisme de suppression des données de session expirée dépend des fonctionnalités de votre source de données. Si votre source de données peut être configurée pour supprimer des données de session expirée par la session Timeout, vous pouvez utiliser la méthode SetItemExpireCallback pour référencer le délégué pour l'événement Session_OnEnd et le déclencher lors de la suppression de données de session expirée.

ApplicationName

Pour gérer la portée de session, les fournisseurs de magasins d'état de session stockent séparément les informations sur les sessions de chaque application. Cela permet à plusieurs applications ASP.NET d'utiliser la même source de données sans avoir de conflit en cas d'identificateurs de session en double.

Dans la mesure où les fournisseurs de magasins d'état de session stockent séparément les informations sur les sessions de chaque application, vous devez vérifier que votre schéma de données, vos requêtes et vos mises à jour incluent le nom de l'application. Par exemple, la commande suivante peut être utilisée pour récupérer des données de session d'une base de données.

SELECT * FROM Sessions 
  WHERE SessionID = 'ABC123' AND ApplicationName = 'MyApplication'

Vous pouvez aussi stocker une combinaison identificateur de session/nom de l'application comme identificateur unique d'un élément dans le magasin de données d'état de session.

Classes requises

Pour implémenter un fournisseur de magasins d'état de session, créez une classe qui hérite la classe abstraite SessionStateStoreProviderBase. La classe SessionStateStoreProviderBase héritant à son tour de la classe abstraite ProviderBase, vous devez aussi implémenter les membres requis de la classe ProviderBase. Les tableaux suivants répertorient et décrivent les propriétés et méthodes que vous devez implémenter à partir des classes abstraites ProviderBase et SessionStateStoreProviderBase. Pour voir une implémentation de chaque membre, consultez Exemple de fournisseur de magasins d'état de session.

Membres ProviderBase requis

Member

Description

Méthode Initialize

Prend en entrée le nom du fournisseur et une instance NameValueCollection des paramètres de configuration. Cette méthode est utilisée pour définir des valeurs de propriété pour l'instance de fournisseur, y compris les valeurs et les options spécifiques à l'implémentation et spécifiées dans le fichier de configuration (Machine.config ou Web.config).

Membres SessionStateStoreProvider requis

Member

Description

Méthode InitializeRequest

Utilise l'instance de HttpContext de la demande actuelle comme données d'entrée et exécute toute initialisation requise par votre fournisseur de magasins d'état de session.

Méthode EndRequest

Utilise l'instance de HttpContext de la demande actuelle comme données d'entrée et exécute tout nettoyage requis par votre fournisseur de magasins d'état de session.

Méthode Dispose

Libère les ressources qui ne sont plus utilisées par le fournisseur de magasins d'état de session.

Méthode GetItemExclusive

Utilise l'instance de HttpContext de la demande actuelle comme données d'entrée et la valeur SessionID pour la demande actuelle. Récupère des valeurs de session et des informations du magasin de données de session et verrouille les données d'élément de session dans le magasin de données pour la durée de la demande. La méthode GetItemExclusive définit des plusieurs valeurs de paramètre de sortie qui informent le SessionStateModule appelant à propos de l'état de l'élément d'état de session actuel dans le magasin de données.

Si aucune donnée de l'élément de la session n'est trouvée dans le magasin de données, la méthode GetItemExclusive affecte la valeur false au paramètre de sortie locked et retourne null. Il en résulte que le SessionStateModule appelle la méthode CreateNewStoreData pour créer un nouvel objet SessionStateStoreData pour la demande.

Si des données d'élément de session sont trouvées dans le magasin de données, mais qu'elles sont verrouillées, la méthode GetItemExclusive affecte la valeur true au paramètre de sortie locked, la date et l'heure actuelles moins la date et l'heure du verrouillage de l'élément au paramètre de sortie lockAge, l'identificateur de verrou est récupéré du magasin de données au paramètre de sortie lockId, et retourne null. Il en résulte que le SessionStateModule appelle de nouveau la méthode GetItemExclusive après un intervalle d'une demi-seconde, pour essayer de récupérer les informations d'élément de session et obtenir un verrouillage des données. Si la valeur affectée au paramètre de sortie lockAge excède la valeur ExecutionTimeout, SessionStateModule appelle la méthode ReleaseItemExclusive pour supprimer le verrouillage des données d'élément de session et appelle encore la méthode GetItemExclusive.

Le paramètre actionFlags est utilisé avec les sessions dont la propriété Cookieless a la valeur true, lorsque la valeur true est affectée à l'attribut regenerateExpiredSessionId. Une valeur actionFlags définie avec InitializeItem (1) indique que l'entrée dans le magasin de données de session correspond à une nouvelle session qui nécessite une initialisation. Les entrées non initialisées dans le magasin de données de session sont créées par un appel à la méthode CreateUninitializedItem. Si l'élément du magasin de données de session est déjà initialisé, la valeur zéro est affectée au paramètre actionFlags.

Si votre fournisseur prend en charge les sessions sans cookie, affectez la valeur retournée par le magasin de données de session pour l'élément actuel au paramètre de sortie actionFlags. Si la valeur du paramètre actionFlags de l'élément de magasin de session demandé est égale à la valeur d'énumération InitializeItem (1), la méthode GetItemExclusive doit affecter zéro à la valeur dans le magasin de données après avoir défini le paramètre actionFlagsout.

Méthode GetItem

Cette méthode effectue le même travail que la méthode GetItemExclusive, sauf qu'elle n'essaie pas d'obtenir le verrouillage de l'élément de session dans le magasin de données. La méthode GetItem est appelée lorsque la valeur ReadOnly est affectée à l'attribut EnableSessionState.

Méthode SetAndReleaseItemExclusive

Utilise comme données d'entrée l'instance de HttpContext de la demande actuelle, la valeur SessionID de la demande actuelle, un objet SessionStateStoreData qui contient les valeurs à stocker de la session actuelle, l'identificateur de verrou de la demande actuelle et une valeur qui indique si les données à stocker concernent une nouvelle session ou une session existante.

Si le paramètre newItem a la valeur true, la méthode SetAndReleaseItemExclusive insère un nouvel élément dans le magasin de données avec les valeurs fournies. Sinon, l'élément existant dans le magasin de données est mis à jour avec les valeurs fournies, et les données sont déverrouillées. Notez que seules les données de session de l'application actuelle qui correspondent à la valeur SessionID et aux valeurs d'identificateur de verrou fournies sont mises à jour.

Après l'appel de la méthode SetAndReleaseItemExclusive, la méthode ResetItemTimeout est appelée par SessionStateModule pour mettre à jour la date et l'heure d'expiration des données d'élément de session.

Méthode ReleaseItemExclusive

Utilise comme données d'entrée l'instance de HttpContext de la demande actuelle, la valeur SessionID de la demande actuelle et l'identificateur de verrou de la demande actuelle, puis déverrouille un élément dans le magasin de données de session. Cette méthode est appelée lorsque la méthode GetItem ou GetItemExclusive est appelée et que le magasin de données spécifie que l'élément demandé est verrouillé, mais que la durée du verrouillage a dépassé la valeur ExecutionTimeout. Le verrouillage est supprimé par cette méthode, et libère l'élément pour qu'il puisse être utilisé par d'autres demandes.

Méthode RemoveItem

Utilise comme données d'entrée l'instance de HttpContext de la demande actuelle, la valeur SessionID de la demande actuelle et l'identificateur de verrou de la demande actuelle, puis supprime les informations sur les sessions du magasin de données où l'élément de magasin de données correspond à la valeur SessionID fournie, à l'application actuelle et à l'identificateur de verrou fourni. Cette méthode est appelée lorsque la méthode Abandon est appelée.

Méthode CreateUninitializedItem

Utilise comme données d'entrée l'instance de HttpContext de la demande actuelle, la valeur SessionID de la demande actuelle et l'identificateur de verrou de la demande actuelle, puis ajoute un élément non initialisé au magasin de données de session avec une valeur actionFlags pour InitializeItem.

La méthode CreateUninitializedItem est utilisée avec les sessions sans cookie lorsque la valeur true est affectée à l'attribut regenerateExpiredSessionId, ce qui a pour résultat que la SessionStateModule génère une nouvelle valeur SessionID lorsqu'un ID de session expiré est détecté.

Le processus de génération d'une nouvelle valeur SessionID exige que le navigateur soit redirigé vers une URL qui contient l'ID de session généré récemment. La méthode CreateUninitializedItem est appelée pendant une demande initiale qui contient un ID de session expiré. Après avoir acquis une nouvelle valeur SessionID pour remplacer l'ID de session expiré, SessionStateModule appelle la méthode CreateUninitializedItem pour ajouter une entrée non initialisée au magasin de données d'état de session. Puis le navigateur est redirigé vers l'URL qui contient la nouvelle valeur SessionID générée. L'existence de l'entrée non initialisée dans le magasin de données de session garantit que la demande redirigée qui contient la nouvelle valeur SessionID générée ne soit pas confondue avec une demande concernant une session expirée et soit plutôt traitée comme une nouvelle session.

L'entrée non initialisée dans le magasin de données de session est associée à la nouvelle valeur SessionID générée et contient uniquement des valeurs par défaut, y compris une date et une heure d'expiration, et une valeur qui correspond au paramètre actionFlags des méthodes GetItem et GetItemExclusive. L'entrée non initialisée dans le magasin d'état de session doit contenir une valeur actionFlags égale à la valeur d'énumération InitializeItem (1). Cette valeur est passée à SessionStateModule par les méthodes GetItem et GetItemExclusive, et spécifie pour SessionStateModule que la session actuelle est une nouvelle session. SessionStateModule initialisera ensuite la nouvelle session et déclenchera l'événement Session_OnStart.

Méthode CreateNewStoreData

Utilise comme données d'entrée l'instance de HttpContext de la demande en cours et la valeur Timeout de la session en cours, et retourne un nouvel objet SessionStateStoreData avec un objet ISessionStateItemCollection vide, une collection HttpStaticObjectsCollection et la valeur Timeout spécifiée. L'instance de HttpStaticObjectsCollection de l'application ASP.NET peut être récupérée à l'aide de la méthode GetSessionStaticObjects.

Méthode SetItemExpireCallback

Utilise comme données en entrée un délégué qui référence l'événement Session_OnEnd défini dans le fichier Global.asax. Si le fournisseur de magasins d'état de session prend en charge l'événement Session_OnEnd, une référence locale au paramètre SessionStateItemExpireCallback est définie et la méthode retourne true ; sinon, la méthode retourne false.

Fournisseur d'exemples

Pour consulter un exemple d'implémentation de fournisseur de magasins d'état de session personnalisé qui gère des informations sur les sessions dans une base de données Access, consultez Exemple de fournisseur de magasins d'état de session.

Voir aussi

Concepts

Exemple de fournisseur de magasins d'état de session

Vue d'ensemble de l'état de session ASP.NET

Vue d'ensemble de la gestion d'état ASP.NET