Stato di sessioni e app in ASP.NET CoreSession and app state in ASP.NET Core

Di Rick Anderson, Steve Smith, Diana LaRose e Luke LathamBy Rick Anderson, Steve Smith, Diana LaRose, and Luke Latham

HTTP è un protocollo senza stato.HTTP is a stateless protocol. Senza eseguire ulteriori passaggi, le richieste HTTP sono messaggi indipendenti che non mantengono i valori dell'utente o lo stato delle app.Without taking additional steps, HTTP requests are independent messages that don't retain user values or app state. In questo articolo vengono descritti diversi approcci per mantenere lo stato di app e dati utente tra le richieste.This article describes several approaches to preserve user data and app state between requests.

Visualizzare o scaricare il codice di esempio (procedura per il download)View or download sample code (how to download)

Gestione dello statoState management

Lo stato può essere archiviato usando diversi approcci.State can be stored using several approaches. Ogni approccio è descritto di seguito in questo argomento.Each approach is described later in this topic.

Approccio con risorsa di archiviazioneStorage approach Meccanismo di archiviazioneStorage mechanism
CookieCookies Cookie HTTP (possono includere dati archiviati usando il codice app lato server)HTTP cookies (may include data stored using server-side app code)
Stato della sessioneSession state Cookie HTTP e codice app lato serverHTTP cookies and server-side app code
TempDataTempData Cookie HTTP o stato della sessioneHTTP cookies or session state
Stringhe di queryQuery strings Stringhe di query HTTPHTTP query strings
Campi nascostiHidden fields Campi dei form HTTPHTTP form fields
HttpContext.ItemsHttpContext.Items Codice app lato serverServer-side app code
CacheCache Codice app lato serverServer-side app code
Inserimento dipendenzeDependency Injection Codice app lato serverServer-side app code

CookieCookies

I cookie archiviano i dati tra le richieste.Cookies store data across requests. Poiché i cookie vengono inviati con ogni richiesta, la loro dimensione deve essere mantenuta al minimo.Because cookies are sent with every request, their size should be kept to a minimum. Idealmente, in un cookie deve essere archiviato solo un identificatore con i dati archiviati dall'app.Ideally, only an identifier should be stored in a cookie with the data stored by the app. La maggior parte dei browser limita la dimensione dei cookie a 4096 byte.Most browsers restrict cookie size to 4096 bytes. Per ogni dominio è disponibile solo un numero limitato di cookie.Only a limited number of cookies are available for each domain.

Poiché i cookie possono essere manomessi, devono essere convalidati dall'app.Because cookies are subject to tampering, they must be validated by the app. I cookie possono essere eliminati dagli utenti e scadono nei client.Cookies can be deleted by users and expire on clients. Tuttavia, i cookie sono in genere la forma più durevole di salvataggio permanente dei dati nel client.However, cookies are generally the most durable form of data persistence on the client.

I cookie vengono spesso usati per la personalizzazione, ovvero il contenuto viene personalizzato per un utente noto.Cookies are often used for personalization, where content is customized for a known user. L'utente viene solo identificato e non autenticato nella maggior parte dei casi.The user is only identified and not authenticated in most cases. Nel cookie può essere memorizzato il nome dell'utente, il nome dell'account o l'ID utente univoco, ad esempio un GUID.The cookie can store the user's name, account name, or unique user ID (such as a GUID). È quindi possibile usare il cookie per accedere alle impostazioni personalizzate dell'utente, ad esempio il colore di sfondo preferito per il sito Web.You can then use the cookie to access the user's personalized settings, such as their preferred website background color.

Tenere presente il Regolamento generale sulla protezione dei dati dell'Unione Europea quando si emettono i cookie e si gestisce la protezione dei dati.Be mindful of the European Union General Data Protection Regulations (GDPR) when issuing cookies and dealing with privacy concerns. Per altre informazioni, vedere il supporto per il Regolamento generale sulla protezione dei dati in ASP.NET Core.For more information, see General Data Protection Regulation (GDPR) support in ASP.NET Core.

Stato sessioneSession state

Lo stato della sessione è uno scenario di ASP.NET Core per l'archiviazione dei dati utente mentre l'utente visualizza un'app Web.Session state is an ASP.NET Core scenario for storage of user data while the user browses a web app. Lo stato della sessione usa un archivio gestito dall'app per rendere persistenti i dati tra le richieste provenienti da un client.Session state uses a store maintained by the app to persist data across requests from a client. I dati della sessione sono supportati da una cache e considerati dati temporanei: il sito deve continuare a funzionare senza i dati della sessione.The session data is backed by a cache and considered ephemeral data—the site should continue to function without the session data. I dati critici dell'applicazione devono essere archiviati nel database utente e memorizzati nella cache della sessione solo al fine di ottimizzare le prestazioni.Critical application data should be stored in the user database and cached in session only as a performance optimization.

Nota

La sessione non è supportata nelle app SignalR poiché un hub SignalR può essere eseguito indipendentemente da un contesto HTTP.Session isn't supported in SignalR apps because a SignalR Hub may execute independent of an HTTP context. Ad esempio, ciò può verificarsi quando una lunga richiesta di polling viene mantenuta aperta da un hub oltre la durata del contesto HTTP della richiesta.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 mantiene lo stato della sessione assegnando un cookie al client che contiene un ID sessione. Tale ID viene inviato all'app con ogni richiesta.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. L'app usa l'ID sessione per recuperare i dati della sessione.The app uses the session ID to fetch the session data.

Lo stato della sessione presenta i comportamenti seguenti:Session state exhibits the following behaviors:

  • Dato che il cookie di sessione è specifico per il browser, le sessioni non vengono condivise tra i browser.Because the session cookie is specific to the browser, sessions aren't shared across browsers.
  • I cookie di sessione vengono eliminati al termine della sessione del browser.Session cookies are deleted when the browser session ends.
  • Se viene ricevuto un cookie per una sessione scaduta, viene creata una nuova sessione che usa lo stesso cookie di sessione.If a cookie is received for an expired session, a new session is created that uses the same session cookie.
  • Le sessioni vuote non vengono conservate: nella sessione deve essere impostato almeno un valore perché la sessione diventi permanente tra le richieste.Empty sessions aren't retained—the session must have at least one value set into it to persist the session across requests. Se una sessione non viene conservata, viene generato un nuovo ID sessione per ogni nuova richiesta.When a session isn't retained, a new session ID is generated for each new request.
  • L'app conserva una sessione per un periodo di tempo limitato dopo l'ultima richiesta.The app retains a session for a limited time after the last request. L'app imposta il timeout della sessione o usa il valore predefinito, pari a 20 minuti.The app either sets the session timeout or uses the default value of 20 minutes. Lo stato sessione è ideale per archiviare i dati utente specifici per una determinata sessione, ma nel caso in cui i dati non richiedano un'archiviazione permanente tra le sessioni.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.
  • I dati della sessione vengono eliminati quando viene chiamata l'implementazione ISession.Clear o alla scadenza della sessione.Session data is deleted either when the ISession.Clear implementation is called or when the session expires.
  • Non esiste un meccanismo predefinito per indicare al codice app che un browser client è stato chiuso o che il cookie di sessione viene eliminato o è scaduto nel 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.
  • I modelli di pagina ASP.NET Core MVC e Razor includono il supporto del Regolamento generale sulla protezione dei dati (GDPR).The ASP.NET Core MVC and Razor pages templates include support for General Data Protection Regulation (GDPR). I cookie di stato della sessione non sono contrassegnati come fondamentali per impostazione predefinita, pertanto lo stato della sessione non è funzionale, a meno che il rilevamento non sia consentito dal visitatore del sito.Session state cookies aren't marked essential by default, so session state isn't functional unless tracking is permitted by the site visitor. Per altre informazioni, vedere Supporto di General Data Protection Regulation (GDPR) in ASP.NET Core.For more information, see Supporto di General Data Protection Regulation (GDPR) in ASP.NET Core.

Avviso

Evitare di archiviare dati sensibili nello stato della sessione.Don't store sensitive data in session state. L'utente potrebbe non chiudere il browser e cancellare il cookie di sessione.The user might not close the browser and clear the session cookie. Alcuni browser mantengono i cookie di sessione validi tra diverse finestre del browser.Some browsers maintain valid session cookies across browser windows. Una sessione può non essere limitata a un solo utente: in tal caso l'utente successivo potrebbe continuare a sfogliare l'app usando lo stesso cookie di sessione.A session might not be restricted to a single user—the next user might continue to browse the app with the same session cookie.

Il provider di cache in memoria archivia i dati della sessione nella memoria del server in cui si trova l'app.The in-memory cache provider stores session data in the memory of the server where the app resides. In uno scenario di server farm:In a server farm scenario:

Configurare lo stato della sessioneConfigure session state

Con il pacchetto Microsoft.AspNetCore.Session, incluso nel metapacchetto Microsoft.AspNetCore.App, è disponibile il middleware per la gestione dello stato della sessione.The Microsoft.AspNetCore.Session package, which is included in the Microsoft.AspNetCore.App metapackage, provides middleware for managing session state. Per abilitare il middleware della sessione, Startup deve contenere:To enable the session middleware, Startup must contain:

Il codice seguente indica come configurare il provider della sessione in memoria con un'implementazione in memoria predefinita di 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.AddDistributedMemoryCache();

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

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

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

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

L'ordine del middleware è importante.The order of middleware is important. Nell'esempio precedente si verifica un'eccezione InvalidOperationException se UseSession viene chiamata dopo UseMvc.In the preceding example, an InvalidOperationException exception occurs when UseSession is invoked after UseMvc. Per altre informazioni, vedere la sezione relativa all'ordine del middleware.For more information, see Middleware Ordering.

HttpContext. Session è disponibile dopo che è stato configurato lo stato della sessione.HttpContext.Session is available after session state is configured.

Non è possibile accedere a HttpContext.Session prima di chiamare UseSession.HttpContext.Session can't be accessed before UseSession has been called.

Non è possibile creare un nuovo cookie di sessione dopo che l'app ha iniziato la scrittura nel flusso di risposte.A new session with a new session cookie can't be created after the app has begun writing to the response stream. L'eccezione viene registrata nel log del server Web e non è visualizzata nel browser.The exception is recorded in the web server log and not displayed in the browser.

Caricare lo stato della sessione in modo asincronoLoad session state asynchronously

Il provider di sessione predefinito in ASP.NET Core carica in modo asincrono i record di sessione dall'archivio di backup IDistributedCache sottostante solo se il metodo ISession.LoadAsync viene chiamato in modo esplicito prima dei metodi TryGetValue, Set o 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. Se LoadAsync non viene chiamato per primo, il record di sessione sottostante viene caricato in modo sincrono e ciò può compromettere le prestazioni su larga scala.If LoadAsync isn't called first, the underlying session record is loaded synchronously, which can incur a performance penalty at scale.

Per fare in modo che le app implementino questo criterio, eseguire il wrapping delle implementazioni DistributedSessionStore e DistributedSession con versioni che generano un'eccezione se il metodo LoadAsync non viene chiamato prima di TryGetValue, Set o 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. Registrare le versioni con wrapping nel contenitore di servizi.Register the wrapped versions in the services container.

Opzioni di sessioneSession options

Per eseguire l'override delle impostazioni predefinite di sessione, usare SessionOptions.To override session defaults, use SessionOptions.

OpzioneOption DESCRIZIONEDescription
CookieCookie Determina le impostazioni usate per creare il cookie.Determines the settings used to create the cookie. Per impostazione predefinita, Name è SessionDefaults.CookieName (.AspNetCore.Session).Name defaults to SessionDefaults.CookieName (.AspNetCore.Session). Per impostazione predefinita, Path è SessionDefaults.CookiePath (/).Path defaults to SessionDefaults.CookiePath (/). SameSite per impostazione predefinita è SameSiteMode.Lax (1).SameSite defaults to SameSiteMode.Lax (1). Per HttpOnly il valore predefinito è true.HttpOnly defaults to true. Per IsEssential il valore predefinito è false.IsEssential defaults to false.
IdleTimeoutIdleTimeout Il valore IdleTimeout indica quanto tempo la sessione può rimanere inattiva prima che il relativo contenuto venga abbandonato.The IdleTimeout indicates how long the session can be idle before its contents are abandoned. Ogni accesso alla sessione reimposta il timeout.Each session access resets the timeout. Si noti che questa impostazione vale solo per il contenuto della sessione, non per il cookie.This setting only applies to the content of the session, not the cookie. Il valore predefinito è 20 minuti.The default is 20 minutes.
IOTimeoutIOTimeout L'intervallo di tempo massimo consentito per caricare una sessione dall'archivio o per eseguirne il commit nell'archivio.The maximum amount of time allowed to load a session from the store or to commit it back to the store. Questa impostazione può essere applicabile solo alle operazioni asincrone.This setting may only apply to asynchronous operations. Questo timeout può essere disattivato usando InfiniteTimeSpan.This timeout can be disabled using InfiniteTimeSpan. Il valore predefinito è 1 minuto.The default is 1 minute.

Session usa un cookie per tenere traccia e identificare le richieste provenienti da un solo browser.Session uses a cookie to track and identify requests from a single browser. Per impostazione predefinita, questo cookie è denominato .AspNetCore.Session e usa il percorso /.By default, this cookie is named .AspNetCore.Session, and it uses a path of /. Poiché il cookie predefinito non specifica un dominio, non viene reso disponibile allo script lato client nella pagina (perché il valore predefinito di HttpOnly è true).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).

Per eseguire l'override delle impostazioni predefinite della sessione con cookie, usare 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_2);

    services.AddSession(options =>
    {
        options.Cookie.Name = ".AdventureWorks.Session";
        options.IdleTimeout = TimeSpan.FromSeconds(10);
        options.Cookie.IsEssential = true;
    });
}

L'app usa la proprietà IdleTimeout per determinare quanto tempo una sessione può rimanere inattiva prima che il relativo contenuto nella cache del server venga abbandonato.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. Questa proprietà è indipendente dalla scadenza del cookie.This property is independent of the cookie expiration. Ogni richiesta che passa attraverso il middleware di sessione reimposta il timeout.Each request that passes through the Session Middleware resets the timeout.

Lo stato della sessione è non di blocco.Session state is non-locking. Se due richieste tentano simultaneamente di modificare il contenuto di una sessione, l'ultima richiesta sostituisce la prima.If two requests simultaneously attempt to modify the contents of a session, the last request overrides the first. Session viene implementata come sessione coerente, ovvero tutto il contenuto viene archiviato insieme.Session is implemented as a coherent session, which means that all the contents are stored together. Quando due richieste tentano di modificare diversi valori della sessione, l'ultima richiesta può sostituire le modifiche apportate alla sessione dalla prima.When two requests seek to modify different session values, the last request may override session changes made by the first.

Impostare e ottenere i valori della sessioneSet and get Session values

Lo stato della sessione è accessibile da una classe PageModel di Razor Pages o una classe Controller di MVC con HttpContext.Session.Session state is accessed from a Razor Pages PageModel class or MVC Controller class with HttpContext.Session. Questa proprietà è un'implementazione di ISession.This property is an ISession implementation.

L'implementazione ISession offre diversi metodi di estensione per impostare e recuperare i valori interi e stringa.The ISession implementation provides several extension methods to set and retrieve integer and string values. I metodi di estensione si trovano nello spazio dei nomi Microsoft.AspNetCore.Http (aggiungere un'istruzione using Microsoft.AspNetCore.Http; per ottenere l'accesso ai metodi di estensione) quando al pacchetto Microsoft.AspNetCore.Http.Extensions fa riferimento il progetto.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. Entrambi i pacchetti sono inclusi nel metapacchetto Microsoft.AspNetCore.App.Both packages are included in the Microsoft.AspNetCore.App metapackage.

Metodi di estensione ISession:ISession extension methods:

Nell'esempio seguente viene recuperato il valore di sessione per la chiave IndexModel.SessionKeyName (_Name nell'app di esempio) in una pagina di 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'esempio seguente illustra come impostare e ottenere un intero e una stringa: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);

Tutti i dati della sessione devono essere serializzati per abilitare uno scenario di cache distribuita, anche quando si usa la cache in memoria.All session data must be serialized to enable a distributed cache scenario, even when using the in-memory cache. Sono disponibili serializzatori di stringa e numero (vedere i metodi e i metodi di estensione di ISession).Minimal string and number serializers are provided (see the methods and extension methods of ISession). I tipi complessi devono essere serializzati dall'utente usando un altro meccanismo, ad esempio JSON.Complex types must be serialized by the user using another mechanism, such as JSON.

Aggiungere i seguenti metodi di estensione per impostare e ottenere oggetti serializzabili: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);
    }
}

L'esempio seguente illustra come impostare e ottenere un oggetto serializzabile con i metodi di estensione: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);
}

TempDataTempData

ASP.NET Core espone la proprietà TempData di un modello di pagina di Razor Pages o la proprietà TempData di un controller MVC.ASP.NET Core exposes the TempData property of a Razor Pages page model or TempData of an MVC controller. Questa proprietà archivia i dati finché non viene letta.This property stores data until it's read. I metodi Keep e Peek possono essere usati per esaminare i dati senza eliminazione.The Keep and Peek methods can be used to examine the data without deletion. TempData è particolarmente utile per il reindirizzamento quando i dati sono necessari per più di una richiesta singola.TempData is particularly useful for redirection when data is required for more than a single request. La proprietà TempData viene implementata dai provider TempData usando i cookie o lo stato sessione.TempData is implemented by TempData providers using either cookies or session state.

Provider TempDataTempData providers

Il provider TempData basato su cookie viene usato per impostazione predefinita per archiviare TempData nei cookie.The cookie-based TempData provider is used by default to store TempData in cookies.

I dati del cookie vengono crittografati tramite IDataProtector, codificati con Base64UrlTextEncoder e quindi suddivisi in blocchi.The cookie data is encrypted using IDataProtector, encoded with Base64UrlTextEncoder, then chunked. Dato che il cookie è suddiviso in blocchi, il limite di dimensione per un singolo cookie di ASP.NET Core 1.x non è applicabile.Because the cookie is chunked, the single cookie size limit found in ASP.NET Core 1.x doesn't apply. I dati del cookie non vengono compressi perché la compressione di dati crittografati può comportare problemi di sicurezza, ad esempio con attacchi CRIME e BREACH.The cookie data isn't compressed because compressing encrypted data can lead to security problems such as the CRIME and BREACH attacks. Per altre informazioni sul provider TempData basato sui cookie, vedere CookieTempDataProvider.For more information on the cookie-based TempData provider, see CookieTempDataProvider.

Scegliere un provider TempDataChoose a TempData provider

La scelta di un provider TempData implica diverse considerazioni, tra cui:Choosing a TempData provider involves several considerations, such as:

  1. L'app utilizza già lo stato sessione?Does the app already use session state? Se sì, l'uso del provider TempData con stato sessione non comporta un carico aggiuntivo per l'app (indipendentemente dalla dimensione dei dati).If so, using the session state TempData provider has no additional cost to the app (aside from the size of the data).
  2. L'app usa TempData solo quando necessario e per quantità di dati relativamente piccole (fino a 500 byte)?Does the app use TempData only sparingly for relatively small amounts of data (up to 500 bytes)? Se sì, il provider TempData con cookie aggiunge un piccolo carico di lavoro a ogni richiesta che include TempData.If so, the cookie TempData provider adds a small cost to each request that carries TempData. Se no, il provider TempData con stato sessione può essere utile per evitare sequenze di andata e ritorno di grandi quantità di dati in ogni richiesta fino a quando il contenuto TempData non viene consumato.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'app viene eseguita in un server farm in più server?Does the app run in a server farm on multiple servers? Se sì, non è necessaria un'ulteriore configurazione per usare il provider TempData con cookie di fuori della protezione dei dati (vedere Protezione dei dati di ASP.NET Core e Provider di archiviazione chiavi).If so, there's no additional configuration required to use the cookie TempData provider outside of Data Protection (see Protezione dei dati di ASP.NET Core and Key storage providers).

Nota

La maggior parte dei client Web (ad esempio i Web browser) impone limiti per la dimensione massima di ogni cookie, il numero totale di cookie o entrambe le impostazioni.Most web clients (such as web browsers) enforce limits on the maximum size of each cookie, the total number of cookies, or both. Se si usa il provider TempData con cookie, verificare che l'app non superi tali limiti.When using the cookie TempData provider, verify the app won't exceed these limits. Considerare la dimensione totale dei dati.Consider the total size of the data. Considerare l'aumento delle dimensioni del cookie dovuto a crittografia e suddivisione in blocchi.Account for increases in cookie size due to encryption and chunking.

Configurare il provider TempDataConfigure the TempData provider

Il provider TempData basato su cookie è abilitato per impostazione predefinita.The cookie-based TempData provider is enabled by default.

Per abilitare il provider TempData basato sulla sessione, usare il metodo di estensione 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_2)
        .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();
}

L'ordine del middleware è importante.The order of middleware is important. Nell'esempio precedente si verifica un'eccezione InvalidOperationException se UseSession viene chiamata dopo UseMvc.In the preceding example, an InvalidOperationException exception occurs when UseSession is invoked after UseMvc. Per altre informazioni, vedere la sezione relativa all'ordine del middleware.For more information, see Middleware Ordering.

Importante

Se la destinazione è .NET Framework e si usa il provider TempData basato sulla sessione, aggiungere il pacchetto Microsoft.AspNetCore.Session al progetto.If targeting .NET Framework and using the session-based TempData provider, add the Microsoft.AspNetCore.Session package to the project.

Stringhe di queryQuery strings

È possibile passare una quantità limitata di dati da una richiesta a un'altra aggiungendo i dati alla stringa di query della nuova richiesta.A limited amount of data can be passed from one request to another by adding it to the new request's query string. Questo è utile per l'acquisizione dello stato con una modalità persistente, che consente la condivisione dei collegamenti con stato incorporato tramite posta elettronica o social network.This is useful for capturing state in a persistent manner that allows links with embedded state to be shared through email or social networks. Poiché le stringhe di query dell'URL sono pubbliche, non usare mai le stringhe di query per i dati sensibili.Because URL query strings are public, never use query strings for sensitive data.

OItre alle condivisioni involontarie, i dati presenti nelle stringhe di query possono essere oggetto di attacchi di falsificazione della richiesta tra siti (CSRF, Cross-Site Request Forgery), che ingannano gli utenti autenticati invitandoli a visitare siti pericolosi.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. Gli utenti malintenzionati possono quindi sottrarre dati utente dall'app o eseguire azioni dannose per conto dell'utente.Attackers can then steal user data from the app or take malicious actions on behalf of the user. Qualsiasi stato dell'app o della sessione mantenuto deve garantire la protezione dagli attacchi CSRF.Any preserved app or session state must protect against CSRF attacks. Per altre informazioni, vedere Prevenire attacchi tramite richieste intersito false (XSRF/CSRF).For more information, see Prevent Cross-Site Request Forgery (XSRF/CSRF) attacks.

Campi nascostiHidden fields

I dati possono essere salvati in campi modulo nascosti e pubblicati di nuovo nella richiesta successiva.Data can be saved in hidden form fields and posted back on the next request. Questo si verifica spesso nei moduli a più pagine.This is common in multi-page forms. Poiché il client potenzialmente può alterare i dati, l'app deve sempre ripetere la convalida dei dati archiviati nei campi nascosti.Because the client can potentially tamper with the data, the app must always revalidate the data stored in hidden fields.

HttpContext.ItemsHttpContext.Items

La raccolta HttpContext.Items viene usata per archiviare i dati durante l'elaborazione di una singola richiesta.The HttpContext.Items collection is used to store data while processing a single request. Il contenuto della raccolta viene rimosso al termine dell'elaborazione della richiesta.The collection's contents are discarded after a request is processed. La raccolta Items spesso viene usata per consentire ai componenti o al middleware di comunicare quando operano in momenti diversi durante una richiesta e non è disponibile un metodo diretto per passare i parametri.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.

Nell'esempio seguente middleware aggiunge isVerified alla raccolta 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();
});

In punto successivo della pipeline un altro middleware può accedere al valore di 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"]}");
});

Per il middleware che viene usato da un'unica app sono accettabili le chiavi string.For middleware that's only used by a single app, string keys are acceptable. Il middleware condiviso tra le istanze dell'app deve usare chiavi oggetto univoche per evitare conflitti di chiavi.Middleware shared between app instances should use unique object keys to avoid key collisions. L'esempio seguente illustra come usare una chiave oggetto univoca definita in una classe 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>();
    }
}

Altri elementi di codice possono accedere al valore archiviato in HttpContext.Items usando la chiave esposta dalla classe 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!";

Questo approccio ha anche il vantaggio di eliminare l'uso di stringhe chiave nel codice.This approach also has the advantage of eliminating the use of key strings in the code.

CacheCache

La memorizzazione nella cache è un modo efficiente per archiviare e recuperare dati.Caching is an efficient way to store and retrieve data. L'app può controllare la durata degli elementi della cache.The app can control the lifetime of cached items.

I dati memorizzati nella cache non sono associati a una richiesta, un utente o una sessione specifici.Cached data isn't associated with a specific request, user, or session. Prestare attenzione a non memorizzare nella cache i dati specifici dell'utente che possono essere recuperati dalle richieste di altri utenti.Be careful not to cache user-specific data that may be retrieved by other users' requests.

Per altre informazioni, vedere La memorizzazione nella cache di risposta in ASP.NET Core.For more information, see La memorizzazione nella cache di risposta in ASP.NET Core.

Inserimento di dipendenzeDependency Injection

Usare Dependency Injection (Inserimento di dipendenze) per rendere i dati disponibili a tutti gli utenti:Use Dependency Injection to make data available to all users:

  1. Definire un servizio che contiene i dati.Define a service containing the data. Ad esempio, una classe denominata MyAppData è definita come segue:For example, a class named MyAppData is defined:

    public class MyAppData
    {
        // Declare properties and methods
    }
    
  2. Aggiungere la classe del servizio a Startup.ConfigureServices:Add the service class to Startup.ConfigureServices:

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddSingleton<MyAppData>();
    }
    
  3. Usare la classe del servizio dati: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
        }
    }
    

Errori comuniCommon errors

  • "Unable to resolve service for type 'Microsoft.Extensions.Caching.Distributed.IDistributedCache' while attempting to activate 'Microsoft.AspNetCore.Session.DistributedSessionStore'." (Risoluzione servizio non riuscita per il tipo 'Microsoft.Extensions.Caching.Distributed.IDistributedCache' durante il tentativo di attivazione di 'Microsoft.AspNetCore.Session.DistributedSessionStore')."Unable to resolve service for type 'Microsoft.Extensions.Caching.Distributed.IDistributedCache' while attempting to activate 'Microsoft.AspNetCore.Session.DistributedSessionStore'."

    Questo errore dipende in genere dal fatto che almeno un'implementazione IDistributedCache non è stata configurata.This is usually caused by failing to configure at least one IDistributedCache implementation. Per altre informazioni, vedere Memorizzazione nella cache in ASP.NET Core distribuita e Memorizzare nella cache in memoria in ASP.NET Core.For more information, see Memorizzazione nella cache in ASP.NET Core distribuita and Memorizzare nella cache in memoria in ASP.NET Core.

  • Se il middleware di sessione non riesce a rendere permanente una sessione (ad esempio se l'archivio di backup non è disponibile), registra l'eccezione e la richiesta continua normalmente.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. Ciò provoca un comportamento imprevedibile.This leads to unpredictable behavior.

    Ad esempio, un utente archivia un carrello acquisti nella sessione.For example, a user stores a shopping cart in session. L'utente aggiunge un articolo al carrello ma il commit ha esito negativo.The user adds an item to the cart but the commit fails. L'app non riconosce l'errore e segnala all'utente che l'articolo è stato aggiunto al carrello anche se non è vero.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'approccio consigliato per verificare la presenza di errori è chiamare await feature.Session.CommitAsync(); dal codice dell'app quando l'app termina di scrivere nella sessione.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 genera un'eccezione se l'archivio di backup non è disponibile.CommitAsync throws an exception if the backing store is unavailable. Se CommitAsync ha esito negativo, l'app è in grado di elaborare l'eccezione.If CommitAsync fails, the app can process the exception. LoadAsync viene generata nelle stesse condizioni in cui l'archivio dati non è disponibile.LoadAsync throws under the same conditions where the data store is unavailable.

Risorse aggiuntiveAdditional resources

Ospitare ASP.NET Core in una Web farm