État de session et d’application dans ASP.NET CoreSession and app state in ASP.NET Core

Par Rick Anderson, Steve Smith, Diana LaRose et Luke LathamBy Rick Anderson, Steve Smith, Diana LaRose, and Luke Latham

HTTP est un protocole sans état.HTTP is a stateless protocol. Sans effectuer des étapes supplémentaires, les requêtes HTTP sont des messages indépendants qui ne conservent pas les valeurs utilisateur ou l’état de l’application.Without taking additional steps, HTTP requests are independent messages that don't retain user values or app state. Cet article décrit plusieurs approches pour conserver l’état de l’application et les données utilisateur entre les requêtes.This article describes several approaches to preserve user data and app state between requests.

Affichez ou téléchargez l’exemple de code (procédure de téléchargement)View or download sample code (how to download)

Gestion de l’étatState management

L’état peut être stocké à l’aide de plusieurs approches.State can be stored using several approaches. Chacune d’elles est abordée plus loin dans cette rubrique.Each approach is described later in this topic.

Approche du stockageStorage approach Mécanisme de stockageStorage mechanism
CookiesCookies Cookies HTTP (peuvent inclure des données stockées à l’aide de code d’application côté serveur)HTTP cookies (may include data stored using server-side app code)
État de sessionSession state Cookies HTTP et code d’application côté serveurHTTP cookies and server-side app code
TempDataTempData Cookies HTTP ou état de sessionHTTP cookies or session state
Chaînes de requêteQuery strings Chaînes de requête HTTPHTTP query strings
Champs masquésHidden fields Champs de formulaires HTTPHTTP form fields
HttpContext.ItemsHttpContext.Items Code d’application côté serveurServer-side app code
CacheCache Code d’application côté serveurServer-side app code
Injection de dépendancesDependency Injection Code d’application côté serveurServer-side app code

CookiesCookies

Les cookies stockent des données entre les requêtes.Cookies store data across requests. Les cookies sont envoyés avec chaque requête. Il est donc essentiel de limiter leur taille au minimum.Because cookies are sent with every request, their size should be kept to a minimum. Dans l’idéal, un cookie doit stocker uniquement un identificateur et les données stockées par l’application.Ideally, only an identifier should be stored in a cookie with the data stored by the app. La plupart des navigateurs limitent la taille des cookies à 4096 octets.Most browsers restrict cookie size to 4096 bytes. Seul un nombre limité de cookies est disponible pour chaque domaine.Only a limited number of cookies are available for each domain.

Pour éviter les risques de falsification, les cookies doivent être validés par l’application.Because cookies are subject to tampering, they must be validated by the app. Les cookies peuvent être supprimés par les utilisateurs et ils expirent sur les clients.Cookies can be deleted by users and expire on clients. Toutefois, ils constituent généralement la forme la plus durable de persistance des données sur le client.However, cookies are generally the most durable form of data persistence on the client.

Les cookies servent souvent à personnaliser le contenu pour un utilisateur connu.Cookies are often used for personalization, where content is customized for a known user. L’utilisateur est uniquement identifié, et pas authentifié dans la plupart des cas.The user is only identified and not authenticated in most cases. Le cookie peut stocker le nom de l’utilisateur, le nom du compte ou l’ID utilisateur unique (par exemple un GUID).The cookie can store the user's name, account name, or unique user ID (such as a GUID). Vous pouvez ensuite utiliser le cookie pour accéder aux paramètres personnalisés de l’utilisateur, telles que sa couleur d’arrière-plan de site web par défaut.You can then use the cookie to access the user's personalized settings, such as their preferred website background color.

Tenez compte du Règlement général sur la protection des données (RGPD) de l’Union Européenne lors de l’émission de cookies et de la gestion de la confidentialité.Be mindful of the European Union General Data Protection Regulations (GDPR) when issuing cookies and dealing with privacy concerns. Pour plus d’informations, consultez Prise en charge du règlement général sur la protection des données (RGPD) de l’Union Européenne dans ASP.NET Core.For more information, see General Data Protection Regulation (GDPR) support in ASP.NET Core.

État de sessionSession state

L’état de session est un scénario ASP.NET Core pour le stockage des données utilisateur pendant que l’utilisateur parcourt une application web.Session state is an ASP.NET Core scenario for storage of user data while the user browses a web app. L’état de session utilise un magasin tenu à jour par l’application afin de conserver les données entre les requêtes d’un client.Session state uses a store maintained by the app to persist data across requests from a client. Les données de session sont secondées par un cache et considérées comme des données éphémères (le site doit continuer à fonctionner sans elles).The session data is backed by a cache and considered ephemeral data—the site should continue to function without the session data.

Note

La session n’est pas prise en charge dans les applications SignalR car un hub SignalR peut s’exécuter indépendamment d’un contexte HTTP.Session isn't supported in SignalR apps because a SignalR Hub may execute independent of an HTTP context. Par exemple, cela peut se produire quand une longue requête d’interrogation est ouverte par un hub au-delà de la durée de vie du contexte de la requête HTTP.For example, this can occur when a long polling request is held open by a hub beyond the lifetime of the request's HTTP context.

ASP.NET Core tient à jour l’état de session en fournissant au client un cookie qui contient un ID de session, qui est envoyé à l’application lors de chaque requête.ASP.NET Core maintains session state by providing a cookie to the client that contains a session ID, which is sent to the app with each request. Le serveur utilise l’ID de session pour récupérer les données de session.The app uses the session ID to fetch the session data.

L’état de session présente les comportements suivants :Session state exhibits the following behaviors:

  • Le cookie de session étant propre au navigateur, les sessions ne sont pas partagées par les navigateurs.Because the session cookie is specific to the browser, sessions aren't shared across browsers.
  • Les cookies de session sont supprimés uniquement quand la session se termine.Session cookies are deleted when the browser session ends.
  • Si un cookie est reçu pour une session qui a expiré, une session qui utilise le même cookie de session est créée.If a cookie is received for an expired session, a new session is created that uses the same session cookie.
  • Les sessions vides ne sont pas conservées. La session doit avoir au moins une valeur définie pour pouvoir être conservée entre les requêtes.Empty sessions aren't retained—the session must have at least one value set into it to persist the session across requests. Quand une session n’est pas conservée, un nouvel ID de session est généré pour chaque nouvelle requête.When a session isn't retained, a new session ID is generated for each new request.
  • L’application conserve une session pendant une période limitée après la dernière requête.The app retains a session for a limited time after the last request. L’application définit le délai d’expiration d’une session ou utilise la valeur par défaut de 20 minutes.The app either sets the session timeout or uses the default value of 20 minutes. L’état de session est idéal pour le stockage des données utilisateur qui sont propres à une session particulière, mais où les données ne nécessitent pas un stockage permanent entre les sessions.Session state is ideal for storing user data that's specific to a particular session but where the data doesn't require permanent storage across sessions.
  • Les données de session sont supprimées quand l’implémentation ISession.Clear est appelée ou quand la session expire.Session data is deleted either when the ISession.Clear implementation is called or when the session expires.
  • Il n’existe aucun mécanisme par défaut permettant de signaler au code d’application qu’un navigateur client a été fermé ou que le cookie de session a été supprimé ou a expiré sur le client.There's no default mechanism to inform app code that a client browser has been closed or when the session cookie is deleted or expired on the client.

Avertissement

Ne stockez pas de données sensibles dans l’état de session.Don't store sensitive data in session state. L’utilisateur risque de ne pas fermer le navigateur et de ne pas effacer le cookie de session.The user might not close the browser and clear the session cookie. Certains navigateurs conservent des cookies de session valides entre les fenêtres du navigateur.Some browsers maintain valid session cookies across browser windows. Une session n’est pas toujours limitée à un seul utilisateur ; l’utilisateur suivant risque donc de parcourir l’application avec le même cookie de session.A session might not be restricted to a single user—the next user might continue to browse the app with the same session cookie.

Le fournisseur de cache en mémoire stocke les données de session dans la mémoire du serveur où réside l’application.The in-memory cache provider stores session data in the memory of the server where the app resides. Dans un scénario de batterie de serveurs :In a server farm scenario:

Configurer l’état de sessionConfigure session state

Le package Microsoft.AspNetCore.Session, qui est inclus dans le métapackage Microsoft.AspNetCore.App, fournit un middleware (intergiciel) pour gérer l’état de session.The Microsoft.AspNetCore.Session package, which is included in the Microsoft.AspNetCore.App metapackage, provides middleware for managing session state. Pour activer le middleware Session, Startup doit contenir les éléments suivants :To enable the session middleware, Startup must contain:

Le package Microsoft.AspNetCore.Session fournit un middleware pour gérer l’état de session.The Microsoft.AspNetCore.Session package provides middleware for managing session state. Pour activer le middleware Session, Startup doit contenir les éléments suivants :To enable the session middleware, Startup must contain:

Le code suivant montre comment configurer le fournisseur de session en mémoire avec une implémentation en mémoire par défaut de IDistributedCache :The following code shows how to set up the in-memory session provider with a default in-memory implementation of IDistributedCache:

public class Startup
{
    public void ConfigureServices(IServiceCollection services)
    {
        services.Configure<CookiePolicyOptions>(options =>
        {
            options.CheckConsentNeeded = context => true;
            options.MinimumSameSitePolicy = SameSiteMode.None;
        });

        services.AddDistributedMemoryCache();

        services.AddSession(options =>
        {
            // Set a short timeout for easy testing.
            options.IdleTimeout = TimeSpan.FromSeconds(10);
            options.Cookie.HttpOnly = true;
        });

        services.AddMvc()
            .SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
    }

    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }
        else
        {
            app.UseExceptionHandler("/Error");
            app.UseHsts();
        }

        app.UseHttpsRedirection();
        app.UseStaticFiles();
        app.UseCookiePolicy();
        app.UseSession();
        app.UseHttpContextItemsMiddleware();
        app.UseMvc();
    }
}
public class Startup
{
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddDistributedMemoryCache();

        services.AddSession(options =>
        {
            // Set a short timeout for easy testing.
            options.IdleTimeout = TimeSpan.FromSeconds(10);
            options.CookieHttpOnly = true;
        });

        services.AddMvc();
    }

    public void Configure(IApplicationBuilder app)
    {
        app.UseSession();
        app.UseHttpContextItemsMiddleware();
        app.UseMvc(routes =>
        {
            routes.MapRoute(
                name: "default",
                template: "{controller=Home}/{action=Index}/{id?}");
        });
    }
}

L’ordre des middlewares est important.The order of middleware is important. Dans l’exemple précédent, une exception InvalidOperationException se produit quand UseSession est appelée après UseMvc.In the preceding example, an InvalidOperationException exception occurs when UseSession is invoked after UseMvc. Pour plus d’informations, consultez Ordre des intergiciels (middleware).For more information, see Middleware Ordering.

HttpContext.Session est disponible une fois l’état de session configuré.HttpContext.Session is available after session state is configured.

HttpContext.Session n’est pas accessible avant que UseSession ait été appelée.HttpContext.Session can't be accessed before UseSession has been called.

Il est impossible de créer une nouvelle session avec un nouveau cookie de session une fois que l’application a commencé à écrire dans le flux de réponse.A new session with a new session cookie can't be created after the app has begun writing to the response stream. L’exception est enregistrée dans le journal de serveur web et n’est pas affichée pas dans le navigateur.The exception is recorded in the web server log and not displayed in the browser.

Charger l’état de session de façon asynchroneLoad session state asynchronously

Le fournisseur de session par défaut dans ASP.NET Core charge les enregistrements de session de façon asynchrone à partir du magasin de stockage sous-jacent IDistributedCache uniquement si la méthode ISession.LoadAsync est appelée explicitement avant les méthodes TryGetValue, Set ou Remove.The default session provider in ASP.NET Core loads session records from the underlying IDistributedCache backing store asynchronously only if the ISession.LoadAsync method is explicitly called before the TryGetValue, Set, or Remove methods. Si LoadAsync n’est pas appelée en premier, l’enregistrement de session sous-jacent est chargé de façon synchrone, ce qui peut entraîner une baisse des performances à l’échelle.If LoadAsync isn't called first, the underlying session record is loaded synchronously, which can incur a performance penalty at scale.

Pour forcer les applications à appliquer ce modèle, incluez les implémentations DistributedSessionStore et DistributedSession dans un wrapper, avec des versions qui lèvent une exception si la méthode LoadAsync n’est pas appelée avant TryGetValue, Set ou Remove.To have apps enforce this pattern, wrap the DistributedSessionStore and DistributedSession implementations with versions that throw an exception if the LoadAsync method isn't called before TryGetValue, Set, or Remove. Inscrivez ensuite les versions incluses dans le wrapper auprès du conteneur de services.Register the wrapped versions in the services container.

Options de sessionSession options

Pour remplacer les valeurs par défaut de la session, utilisez SessionOptions.To override session defaults, use SessionOptions.

OptionOption DescriptionDescription
CookieCookie Détermine les paramètres utilisés pour créer le cookie.Determines the settings used to create the cookie. Name prend la valeur SessionDefaults.CookieName (.AspNetCore.Session) par défaut.Name defaults to SessionDefaults.CookieName (.AspNetCore.Session). Path prend la valeur SessionDefaults.CookiePath (/) par défaut.Path defaults to SessionDefaults.CookiePath (/). SameSite prend la valeur SameSiteMode.Lax (1) par défaut.SameSite defaults to SameSiteMode.Lax (1). HttpOnly prend la valeur true par défaut.HttpOnly defaults to true. IsEssential prend la valeur false par défaut.IsEssential defaults to false.
IdleTimeoutIdleTimeout IdleTimeout indique la durée pendant laquelle la session peut être inactive avant que son contenu soit abandonné.The IdleTimeout indicates how long the session can be idle before its contents are abandoned. Chaque accès à la session réinitialise le délai d’expiration.Each session access resets the timeout. Ce paramètre s’applique uniquement au contenu de la session, et non au cookie.This setting only applies to the content of the session, not the cookie. La valeur par défaut est 20 minutes.The default is 20 minutes.
IOTimeoutIOTimeout Durée maximale autorisée pour charger une session à partir du magasin ou pour la valider dans le magasin.The maximim amount of time allowed to load a session from the store or to commit it back to the store. Ce paramètre peut s’appliquer uniquement aux opérations asynchrones.This setting may only apply to asynchronous operations. Vous pouvez désactiver ce délai d’expiration à l’aide de InfiniteTimeSpan.This timeout can be disabled using InfiniteTimeSpan. La valeur par défaut est 1 minute.The default is 1 minute.

Session utilise un cookie pour suivre et identifier les requêtes reçues d’un navigateur.Session uses a cookie to track and identify requests from a single browser. Par défaut, ce cookie se nomme .AspNetCore.Session et utilise le chemin /.By default, this cookie is named .AspNetCore.Session, and it uses a path of /. Étant donné que le cookie par défaut ne spécifie pas de domaine, il n’est pas mis à disposition du script côté client dans la page (car HttpOnly a la valeur true par défaut).Because the cookie default doesn't specify a domain, it isn't made available to the client-side script on the page (because HttpOnly defaults to true).

OptionOption DescriptionDescription
CookieDomainCookieDomain Détermine le domaine utilisé pour créer le cookie.Determines the domain used to create the cookie. CookieDomain n’est pas défini par défaut.CookieDomain isn't set by default.
CookieHttpOnlyCookieHttpOnly Détermine si le navigateur doit autoriser le code JavaScript côté client à accéder au cookie.Determines if the browser should allow the cookie to be accessed by client-side JavaScript. La valeur par défaut est true, ce qui signifie que le cookie est transmis uniquement aux requêtes HTTP et n’est pas accessible au script dans la page.The default is true, which means the cookie is only passed to HTTP requests and isn't made available to script on the page.
CookieNameCookieName Détermine le nom du cookie utilisé pour conserver l’ID de session.Determines the cookie name used to persist the session ID. La valeur par défaut est SessionDefaults.CookieName (.AspNetCore.Session).The default is SessionDefaults.CookieName (.AspNetCore.Session).
CookiePathCookiePath Détermine le chemin utilisé pour créer le cookie.Determines the path used to create the cookie. La valeur par défaut est SessionDefaults.CookiePath (/).Defaults to SessionDefaults.CookiePath (/).
CookieSecureCookieSecure Détermine si le cookie doit être transmis uniquement lors des requêtes HTTPS.Determines if the cookie should only be transmitted on HTTPS requests. La valeur par défaut est CookieSecurePolicy.None (2).The default is CookieSecurePolicy.None (2).
IdleTimeoutIdleTimeout IdleTimeout indique la durée pendant laquelle la session peut être inactive avant que son contenu soit abandonné.The IdleTimeout indicates how long the session can be idle before its contents are abandoned. Chaque accès à la session réinitialise le délai d’expiration.Each session access resets the timeout. Notez que cela s’applique uniquement au contenu de la session, et non au cookie.Note this only applies to the content of the session, not the cookie. La valeur par défaut est 20 minutes.The default is 20 minutes.

Session utilise un cookie pour suivre et identifier les requêtes reçues d’un navigateur.Session uses a cookie to track and identify requests from a single browser. Par défaut, ce cookie se nomme .AspNet.Session et utilise le chemin /.By default, this cookie is named .AspNet.Session, and it uses a path of /.

Pour substituer les valeurs de session de cookie par défaut, utilisez SessionOptions :To override cookie session defaults, use SessionOptions:

public void ConfigureServices(IServiceCollection services)
{
    services.Configure<CookiePolicyOptions>(options =>
    {
        options.CheckConsentNeeded = context => true;
        options.MinimumSameSitePolicy = SameSiteMode.None;
    });

    services.AddDistributedMemoryCache();

    services.AddMvc()
        .SetCompatibilityVersion(CompatibilityVersion.Version_2_1);

    services.AddSession(options =>
    {
        options.Cookie.Name = ".AdventureWorks.Session";
        options.IdleTimeout = TimeSpan.FromSeconds(10);
    });
}
public void ConfigureServices(IServiceCollection services)
{
    services.AddDistributedMemoryCache();

    services.AddSession(options =>
    {
        options.CookieName = ".AdventureWorks.Session";
        options.IdleTimeout = TimeSpan.FromSeconds(10);
    });

    services.AddMvc();
}

L’application utilise la propriété IdleTimeout pour déterminer la durée pendant laquelle une session peut rester inactive avant que son contenu dans le cache du serveur soit abandonné.The app uses the IdleTimeout property to determine how long a session can be idle before its contents in the server's cache are abandoned. Cette propriété est indépendante du délai d’expiration du cookie.This property is independent of the cookie expiration. Chaque requête qui passe par le middleware Session réinitialise le délai d’expiration.Each request that passes through the Session Middleware resets the timeout.

L’état de session est sans verrouillage.Session state is non-locking. Si deux requêtes tentent simultanément de modifier le contenu d’une session, la dernière requête remplace la première.If two requests simultaneously attempt to modify the contents of a session, the last request overrides the first. Session est implémentée comme une session cohérente, ce qui signifie que tout le contenu est stocké au même emplacement.Session is implemented as a coherent session, which means that all the contents are stored together. Quand deux requêtes tentent de modifier différentes valeurs de session, la dernière requête peut remplacer les modifications de session effectuées par la première.When two requests seek to modify different session values, the last request may override session changes made by the first.

Définir et obtenir des valeurs SessionSet and get Session values

L’état de session est accessible à partir d’une classe Razor Pages PageModel ou d’une classe MVC Controller avec HttpContext.Session.Session state is accessed from a Razor Pages PageModel class or MVC Controller class with HttpContext.Session. Cette propriété est une implémentation ISession.This property is an ISession implementation.

L’implémentation ISession fournit plusieurs méthodes d’extension pour définir et récupérer des valeurs de chaîne et des entiers.The ISession implementation provides several extension methods to set and retreive integer and string values. Les méthodes d’extension se trouvent dans l’espace de noms Microsoft.AspNetCore.Http (ajoutez une instruction using Microsoft.AspNetCore.Http; pour accéder aux méthodes d’extension) quand le package Microsoft.AspNetCore.Http.Extensions est référencé par le projet.The extension methods are in the Microsoft.AspNetCore.Http namespace (add a using Microsoft.AspNetCore.Http; statement to gain access to the extension methods) when the Microsoft.AspNetCore.Http.Extensions package is referenced by the project. Les deux packages sont inclus dans le métapackage Microsoft.AspNetCore.App.Both packages are included in the Microsoft.AspNetCore.App metapackage.

L’implémentation ISession fournit plusieurs méthodes d’extension pour définir et récupérer des valeurs de chaîne et des entiers.The ISession implementation provides several extension methods to set and retreive integer and string values. Les méthodes d’extension se trouvent dans l’espace de noms Microsoft.AspNetCore.Http (ajoutez une instruction using Microsoft.AspNetCore.Http; pour accéder aux méthodes d’extension) quand le package Microsoft.AspNetCore.Http.Extensions est référencé par le projet.The extension methods are in the Microsoft.AspNetCore.Http namespace (add a using Microsoft.AspNetCore.Http; statement to gain access to the extension methods) when the Microsoft.AspNetCore.Http.Extensions package is referenced by the project.

Méthodes d’extension ISession :ISession extension methods:

L’exemple suivant récupère la valeur de session pour la clé IndexModel.SessionKeyName (_Name dans l’exemple d’application) dans une page Razor Pages :The following example retrieves the session value for the IndexModel.SessionKeyName key (_Name in the sample app) in a Razor Pages page:

@page
@using Microsoft.AspNetCore.Http
@model IndexModel

...

Name: @HttpContext.Session.GetString(IndexModel.SessionKeyName)

L’exemple suivant montre comment définir et obtenir un entier et une chaîne :The following example shows how to set and get an integer and a string:

public class IndexModel : PageModel
{
    public const string SessionKeyName = "_Name";
    public const string SessionKeyAge = "_Age";
    const string SessionKeyTime = "_Time";

    public string SessionInfo_Name { get; private set; }
    public string SessionInfo_Age { get; private set; }
    public string SessionInfo_CurrentTime { get; private set; }
    public string SessionInfo_SessionTime { get; private set; }
    public string SessionInfo_MiddlewareValue { get; private set; }

    public void OnGet()
    {
        // Requires: using Microsoft.AspNetCore.Http;
        if (string.IsNullOrEmpty(HttpContext.Session.GetString(SessionKeyName)))
        {
            HttpContext.Session.SetString(SessionKeyName, "The Doctor");
            HttpContext.Session.SetInt32(SessionKeyAge, 773);
        }

        var name = HttpContext.Session.GetString(SessionKeyName);
        var age = HttpContext.Session.GetInt32(SessionKeyAge);
public class HomeController : Controller
{
    const string SessionKeyName = "_Name";
    const string SessionKeyYearsMember = "_YearsMember";
    const string SessionKeyDate = "_Date";

    public IActionResult Index()
    {
        // Requires using Microsoft.AspNetCore.Http;
        HttpContext.Session.SetString(SessionKeyName, "Rick");
        HttpContext.Session.SetInt32(SessionKeyYearsMember, 3);

        return RedirectToAction("SessionNameYears");
    }

    public IActionResult SessionNameYears()
    {
        var name = HttpContext.Session.GetString(SessionKeyName);
        var yearsMember = HttpContext.Session.GetInt32(SessionKeyYearsMember);

        return Content($"Name: \"{name}\",  Membership years: \"{yearsMember}\"");
    }

Toutes les données de session doivent être sérialisées pour activer un scénario de cache distribué, même si vous utilisez le cache en mémoire.All session data must be serialized to enable a distributed cache scenario, even when using the in-memory cache. Des sérialiseurs de nombres et de chaînes minimaux sont fournis (voir les méthodes et les méthodes d’extension de ISession).Minimal string and number serializers are provided (see the methods and extension methods of ISession). Les types complexes doivent être sérialisés par l’utilisateur à l’aide d’un autre mécanisme, tel que JSON.Complex types must be serialized by the user using another mechanism, such as JSON.

Ajoutez les méthodes d’extension suivantes pour définir et obtenir des objets sérialisables :Add the following extension methods to set and get serializable objects:

public static class SessionExtensions
{
    public static void Set<T>(this ISession session, string key, T value)
    {
        session.SetString(key, JsonConvert.SerializeObject(value));
    }

    public static T Get<T>(this ISession session, string key)
    {
        var value = session.GetString(key);

        return value == null ? default(T) : 
            JsonConvert.DeserializeObject<T>(value);
    }
}
public static class SessionExtensions
{
    public static void Set<T>(this ISession session, string key, T value)
    {
        session.SetString(key, JsonConvert.SerializeObject(value));
    }

    public static T Get<T>(this ISession session,string key)
    {
        var value = session.GetString(key);
        return value == null ? default(T) : 
            JsonConvert.DeserializeObject<T>(value);
    }
}

L’exemple suivant montre comment définir et obtenir un objet sérialisable avec les méthodes d’extension :The following example shows how to set and get a serializable object with the extension methods:

// Requires you add the Set and Get extension method mentioned in the topic.
if (HttpContext.Session.Get<DateTime>(SessionKeyTime) == default(DateTime))
{
    HttpContext.Session.Set<DateTime>(SessionKeyTime, currentTime);
}
public IActionResult SetDate()
{
    // Requires you add the Set extension method mentioned in the topic.
    HttpContext.Session.Set<DateTime>(SessionKeyDate, DateTime.Now);

    return RedirectToAction("GetDate");
}

public IActionResult GetDate()
{
    // Requires you add the Get extension method mentioned in the topic.
    var date = HttpContext.Session.Get<DateTime>(SessionKeyDate);
    var sessionTime = date.TimeOfDay.ToString();
    var currentTime = DateTime.Now.TimeOfDay.ToString();

    return Content($"Current time: {currentTime} - "
                 + $"session time: {sessionTime}");
}

TempDataTempData

ASP.NET Core expose la propriété TempData d’un modèle de page Razor Pages ou TempData d’un contrôleur MVC.ASP.NET Core exposes the TempData property of a Razor Pages page model or TempData of an MVC controller. Cette propriété stocke les données jusqu’à ce qu’elles soient lues.This property stores data until it's read. Vous pouvez utiliser les méthodes Keep et Peek pour examiner les données sans suppression.The Keep and Peek methods can be used to examine the data without deletion. TempData est particulièrement utile pour la redirection, quand des données sont nécessaires pour plusieurs requêtes.TempData is particularly useful for redirection when data is required for more than a single request. TempData est implémenté par des fournisseurs TempData à l’aide de cookies ou de l’état de session.TempData is implemented by TempData providers using either cookies or session state.

Fournisseurs TempDataTempData providers

Dans ASP.NET Core 2.0 ou ultérieur, le fournisseur TempData basé sur les cookies est utilisé par défaut pour stocker TempData dans des cookies.In ASP.NET Core 2.0 or later, the cookie-based TempData provider is used by default to store TempData in cookies.

Les données de cookie sont chiffrées avec IDataProtector, encodées avec Base64UrlTextEncoder, puis mémorisées en bloc.The cookie data is encrypted using IDataProtector, encoded with Base64UrlTextEncoder, then chunked. Étant donné que le cookie est mémorisé en bloc, la limite de taille d’un cookie définie dans ASP.NET Core 1.x ne s’applique pas.Because the cookie is chunked, the single cookie size limit found in ASP.NET Core 1.x doesn't apply. Les données de cookie ne sont pas compressées, car la compression de données chiffrées peut entraîner des problèmes de sécurité, notamment des attaques CRIME et BREACH.The cookie data isn't compressed because compressing encrypted data can lead to security problems such as the CRIME and BREACH attacks. Pour plus d’informations sur le fournisseur TempData basé sur les cookies, consultez CookieTempDataProvider.For more information on the cookie-based TempData provider, see CookieTempDataProvider.

Dans ASP.NET Core 1.0 et 1.1, le fournisseur TempData d’état de session est le fournisseur par défaut.In ASP.NET Core 1.0 and 1.1, the session state TempData provider is the default provider.

Choisir un fournisseur TempDataChoose a TempData provider

Pour choisir un fournisseur TempData, vous devez tenir compte de plusieurs points. Par exemple :Choosing a TempData provider involves several considerations, such as:

  1. L’application utilise-t-elle déjà l’état de session ?Does the app already use session state? Si c’est le cas, l’utilisation du fournisseur TempData d’état de session n’entraîne pas de surcoût pour l’application (hormis la taille des données).If so, using the session state TempData provider has no additional cost to the app (aside from the size of the data).
  2. L’application utilise-t-elle TempData seulement de façon ponctuelle, pour des quantités de données relativement petites (jusqu’à 500 octets) ?Does the app use TempData only sparingly for relatively small amounts of data (up to 500 bytes)? Si c’est le cas, le fournisseur TempData de cookies ajoute un petit coût à chaque requête traitée par TempData.If so, the cookie TempData provider adds a small cost to each request that carries TempData. Si ce n’est pas le cas, le fournisseur TempData d’état de session peut être utile pour éviter l’aller-retour d’une grande quantité de données dans chaque requête jusqu’à ce que le TempData soit consommé.If not, the session state TempData provider can be beneficial to avoid round-tripping a large amount of data in each request until the TempData is consumed.
  3. L’application s’exécute-t-elle dans une batterie de serveurs sur plusieurs serveurs ?Does the app run in a server farm on multiple servers? Si c’est le cas, aucune configuration supplémentaire n’est nécessaire pour utiliser le fournisseur TempData de cookies en dehors de la Protection des données (consultez Protection des données ASP.NET Core et Fournisseurs de stockage de clés).If so, there's no additional configuration required to use the cookie TempData provider outside of Data Protection (see Protection des données ASP.NET Core and Key storage providers).

Note

La plupart des clients web (par exemple, les navigateurs web) appliquent des limites pour la taille maximale de chaque cookie et/ou le nombre total de cookies.Most web clients (such as web browsers) enforce limits on the maximum size of each cookie, the total number of cookies, or both. Quand vous utilisez le fournisseur TempData de cookies, vérifiez que l’application ne dépasse pas ces limites.When using the cookie TempData provider, verify the app won't exceed these limits. Prenez en compte la taille totale des données.Consider the total size of the data. Pensez aux augmentations de taille de cookie dues au chiffrement et à la segmentation.Account for increases in cookie size due to encryption and chunking.

Configuration du fournisseur TempDataConfigure the TempData provider

Le fournisseur TempData basé sur les cookies est activé par défaut.The cookie-based TempData provider is enabled by default.

Pour activer le fournisseur TempData basé sur la session, utilisez la méthode d’extension AddSessionStateTempDataProvider :To enable the session-based TempData provider, use the AddSessionStateTempDataProvider extension method:

public void ConfigureServices(IServiceCollection services)
{
    services.Configure<CookiePolicyOptions>(options =>
    {
        options.CheckConsentNeeded = context => true;
        options.MinimumSameSitePolicy = SameSiteMode.None;
    });

    services.AddMvc()
        .SetCompatibilityVersion(CompatibilityVersion.Version_2_1)
        .AddSessionStateTempDataProvider();

    services.AddSession();
}

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
        app.UseDatabaseErrorPage();
    }
    else
    {
        app.UseExceptionHandler("/Error");
        app.UseHsts();
    }

    app.UseHttpsRedirection();
    app.UseStaticFiles();
    app.UseCookiePolicy();
    app.UseSession();
    app.UseMvc();
}

Le code de classe Startup suivant configure le fournisseur TempData basé sur les sessions :The following Startup class code configures the session-based TempData provider:

public void ConfigureServices(IServiceCollection services)
{
    services.AddMvc();
    services.AddSession();
}

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
    app.UseSession();
    app.UseMvc(routes =>
    {
        routes.MapRoute(
            name: "default",
            template: "{controller=Home}/{action=Index}/{id?}");
    });
}

L’ordre des middlewares est important.The order of middleware is important. Dans l’exemple précédent, une exception InvalidOperationException se produit quand UseSession est appelée après UseMvc.In the preceding example, an InvalidOperationException exception occurs when UseSession is invoked after UseMvc. Pour plus d’informations, consultez Ordre des intergiciels (middleware).For more information, see Middleware Ordering.

Important

Si vous ciblez le .NET Framework et que vous utilisez le fournisseur TempData basé sur la session, ajoutez le package Microsoft.AspNetCore.Session au projet.If targeting .NET Framework and using the session-based TempData provider, add the Microsoft.AspNetCore.Session package to the project.

Chaînes de requêteQuery strings

Vous pouvez passer une quantité limitée de données d’une requête à une autre en l’ajoutant à la chaîne de la nouvelle requête.A limited amount of data can be passed from one request to another by adding it to the new request's query string. Cela est utile pour capturer l’état de manière persistante et permettre ainsi le partage de liens avec état incorporé par e-mail ou sur les réseaux sociaux.This is useful for capturing state in a persistent manner that allows links with embedded state to be shared through email or social networks. Les chaînes de requête URL étant publiques, vous ne devez jamais utiliser de chaînes de requête pour des données sensibles.Because URL query strings are public, never use query strings for sensitive data.

En plus du partage accidentel, l’ajout de données dans des chaînes de requête peut favoriser les attaques par falsification de requête intersites (CSRF, Cross Site Request Forgery) et conduire des utilisateurs authentifiés à visiter des sites malveillants.In addition to unintended sharing, including data in query strings can create opportunities for Cross-Site Request Forgery (CSRF) attacks, which can trick users into visiting malicious sites while authenticated. Les attaquants peuvent ensuite dérober des données utilisateur à partir de l’application ou effectuer des actions malveillantes en utilisant un compte d’utilisateur.Attackers can then steal user data from the app or take malicious actions on behalf of the user. Chaque état de session ou d’application conservé doit garantir une protection contre les attaques CSRF.Any preserved app or session state must protect against CSRF attacks. Pour plus d’informations, consultez Empêcher les attaques par falsification de requête intersites (XSRF/CSRF).For more information, see Prevent Cross-Site Request Forgery (XSRF/CSRF) attacks.

Champs masquésHidden fields

Les données peuvent être enregistrées dans des champs de formulaire masqués et être republiées lors de la requête suivante.Data can be saved in hidden form fields and posted back on the next request. Cela est courant dans les formulaires de plusieurs pages.This is common in multi-page forms. Étant donné que le client peut potentiellement falsifier les données, l’application doit toujours revalider les données stockées dans les champs masqués.Because the client can potentially tamper with the data, the app must always revalidate the data stored in hidden fields.

HttpContext.ItemsHttpContext.Items

La collection HttpContext.Items est utilisée pour stocker les données lors du traitement d’une seule requête.The HttpContext.Items collection is used to store data while processing a single request. Le contenu de la collection est supprimé une fois la requête traitée.The collection's contents are discarded after a request is processed. La collection Items est souvent utilisée pour permettre à des composants ou des middlewares de communiquer quand ils opèrent à différents moments de l’exécution d’une requête et qu’ils ne peuvent pas passer les paramètres de façon directe.The Items collection is often used to allow components or middleware to communicate when they operate at different points in time during a request and have no direct way to pass parameters.

Dans l’exemple suivant, le middleware ajoute isVerified à la collection Items.In the following example, middleware adds isVerified to the Items collection.

app.Use(async (context, next) =>
{
    // perform some verification
    context.Items["isVerified"] = true;
    await next.Invoke();
});

Plus tard dans le pipeline, un autre middleware peut accéder à la valeur de isVerified :Later in the pipeline, another middleware can access the value of isVerified:

app.Run(async (context) =>
{
    await context.Response.WriteAsync($"Verified: {context.Items["isVerified"]}");
});

Si un middleware est destiné uniquement à l’usage d’une seule application, les clés string sont acceptables.For middleware that's only used by a single app, string keys are acceptable. Le middleware partagé entre des instances de l’application doit utiliser des clés d’objets uniques afin d’éviter les conflits de clé.Middleware shared between app instances should use unique object keys to avoid key collisions. L’exemple suivant montre comment utiliser une clé d’objet unique définie dans une classe de middleware :The following example shows how to use a unique object key defined in a middleware class:

public class HttpContextItemsMiddleware
{
    private readonly RequestDelegate _next;
    public static readonly object HttpContextItemsMiddlewareKey = new Object();

    public HttpContextItemsMiddleware(RequestDelegate next)
    {
        _next = next;
    }

    public async Task Invoke(HttpContext httpContext)
    {
        httpContext.Items[HttpContextItemsMiddlewareKey] = "K-9";

        await _next(httpContext);
    }
}

public static class HttpContextItemsMiddlewareExtensions
{
    public static IApplicationBuilder 
        UseHttpContextItemsMiddleware(this IApplicationBuilder builder)
    {
        return builder.UseMiddleware<HttpContextItemsMiddleware>();
    }
}
// You may need to install the Microsoft.AspNetCore.Http.Abstractions package
public class HttpContextItemsMiddleware
{
    private readonly RequestDelegate _next;
    public static readonly object HttpContextItemsMiddlewareKey = new Object();

    public HttpContextItemsMiddleware(RequestDelegate next)
    {
        _next = next;
    }

    public async Task Invoke(HttpContext httpContext)
    {
        httpContext.Items[HttpContextItemsMiddlewareKey] = "K-9";

        await _next(httpContext);
    }
}

public static class HttpContextItemsMiddlewareExtensions
{
    public static IApplicationBuilder 
        UseHttpContextItemsMiddleware(this IApplicationBuilder builder)
    {
        return builder.UseMiddleware<HttpContextItemsMiddleware>();
    }
}

Tout autre code peut accéder à la valeur stockée dans HttpContext.Items à l’aide de la clé exposée par la classe du middleware :Other code can access the value stored in HttpContext.Items using the key exposed by the middleware class:

HttpContext.Items
    .TryGetValue(HttpContextItemsMiddleware.HttpContextItemsMiddlewareKey, 
        out var middlewareSetValue);
SessionInfo_MiddlewareValue = 
    middlewareSetValue?.ToString() ?? "Middleware value not set!";
public IActionResult GetMiddlewareValue()
{
    var middlewareSetValue = 
        HttpContext.Items[HttpContextItemsMiddleware.HttpContextItemsMiddlewareKey];

    return Content($"Value: {middlewareSetValue}");
}

Cette approche a également l’avantage d’éliminer l’utilisation des chaînes de clés dans le code.This approach also has the advantage of eliminating the use of key strings in the code.

d'instance/de cléCache

La mise en cache est un moyen efficace de stocker et récupérer des données.Caching is an efficient way to store and retrieve data. L’application peut contrôler la durée de vie des éléments mis en cache.The app can control the lifetime of cached items.

Les données mises en cache ne sont pas associées à une requête, un utilisateur ou une session spécifique.Cached data isn't associated with a specific request, user, or session. Veillez à ne pas mettre en cache des données propres à l’utilisateur susceptibles d’être récupérées par les requêtes d’autres utilisateurs.Be careful not to cache user-specific data that may be retrieved by other users' requests.

Pour plus d'informations, consultez Mise en cache de la réponse dans ASP.NET Core.For more information, see Mise en cache de la réponse dans ASP.NET Core.

Injection de dépendancesDependency Injection

Utilisez l’injection de dépendances pour rendre les données accessibles à tous les utilisateurs :Use Dependency Injection to make data available to all users:

  1. Définissez un service contenant les données.Define a service containing the data. Par exemple, une classe nommée MyAppData est définie :For example, a class named MyAppData is defined:

    public class MyAppData
    {
        // Declare properties and methods
    }
    
  2. Ajoutez la classe de service à Startup.ConfigureServices :Add the service class to Startup.ConfigureServices:

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddSingleton<MyAppData>();
    }
    
  3. Consommez la classe de service de données :Consume the data service class:

    public class IndexModel : PageModel
    {
        public IndexModel(MyAppData myService)
        {
            // Do something with the service
            //    Examples: Read data, store in a field or property
        }
    }
    
    public class HomeController : Controller
    {
        public HomeController(MyAppData myService)
        {
            // Do something with the service
            //    Examples: Read data, store in a field or property
        }
    }
    

Erreurs courantesCommon errors

  • « Impossible de résoudre le service pour le type 'Microsoft.Extensions.Caching.Distributed.IDistributedCache' lors de la tentative d’activation de 'Microsoft.AspNetCore.Session.DistributedSessionStore'. »"Unable to resolve service for type 'Microsoft.Extensions.Caching.Distributed.IDistributedCache' while attempting to activate 'Microsoft.AspNetCore.Session.DistributedSessionStore'."

    Cette erreur est généralement due à un échec de configuration d’au moins une implémentation IDistributedCache.This is usually caused by failing to configure at least one IDistributedCache implementation. Pour plus d’informations, consultez Mise en cache dans ASP.NET Core distribuée et Mettre en cache en mémoire dans ASP.NET Core.For more information, see Mise en cache dans ASP.NET Core distribuée and Mettre en cache en mémoire dans ASP.NET Core.

  • Dans le cas où le middleware Session ne parvient pas à rendre une session persistante (par exemple si le magasin de stockage n’est pas disponible), il enregistre l’exception dans le journal et la requête se poursuit normalement.In the event that the session middleware fails to persist a session (for example, if the backing store isn't available), the middleware logs the exception and the request continues normally. Cela entraîne un comportement imprévisible.This leads to unpredictable behavior.

    Par exemple, imaginez qu’un utilisateur stocke un panier d’achat dans la session.For example, a user stores a shopping cart in session. Il ajoute un élément au panier, mais la validation échoue.The user adds an item to the cart but the commit fails. L’application n’a pas connaissance de l’échec et signale donc à l’utilisateur que l’élément a été ajouté au panier, ce qui est faux.The app doesn't know about the failure so it reports to the user that the item was added to their cart, which isn't true.

    L’approche recommandée pour rechercher les erreurs de ce type consiste à appeler await feature.Session.CommitAsync(); à partir du code d’application quand l’application a terminé d’écrire dans la session.The recommended approach to check for errors is to call await feature.Session.CommitAsync(); from app code when the app is done writing to the session. CommitAsync lève une exception si le magasin de stockage n’est pas disponible.CommitAsync throws an exception if the backing store is unavailable. Si CommitAsync échoue, l’application peut traiter l’exception.If CommitAsync fails, the app can process the exception. LoadAsync lève une exception dans les mêmes conditions, quand le magasin de données n’est pas disponible.LoadAsync throws under the same conditions where the data store is unavailable.

Ressources supplémentairesAdditional resources

Héberger ASP.NET Core dans une batterie de serveurs web