Memorizzazione nella cache delle risposte in ASP.NET Core

Di Rick Anderson e Kirk Larkin

La memorizzazione nella cache delle risposte riduce il numero di richieste eseguite da un client o un proxy a un server Web. La memorizzazione nella cache delle risposte riduce anche la quantità di lavoro eseguita dal server Web per generare una risposta. La memorizzazione nella cache delle risposte viene impostata nelle intestazioni.

L'attributo ResponseCache imposta le intestazioni di memorizzazione nella cache delle risposte. I client e i proxy intermedi devono rispettare le intestazioni per la memorizzazione nella cache delle risposte secondo la specifica RFC 9111: caching HTTP.

Per la memorizzazione nella cache lato server che segue la specifica HTTP 1.1, usare il middleware di caching delle risposte. Il middleware può usare le proprietà ResponseCacheAttribute per influenzare il comportamento di memorizzazione nella cache lato server.

Il middleware di memorizzazione nella cache della risposta consente la memorizzazione nella cache delle risposte del server in base alle intestazioni HTTP Cache-Control.

  • Il comportamento di memorizzazione nella cache implementa la semantica di memorizzazione nella cache HTTP standard.

  • La memorizzazione nella cache si basa su intestazioni della cache HTTP simili al metodo usato dai proxy.

  • Questa forma di memorizzazione nella cache è utile per le richieste API GET o HEAD pubbliche dai client in cui vengono soddisfatte le condizioni per la memorizzazione nella cache .

  • Per le app dell'interfaccia utente come Razor Pages, la memorizzazione nella cache delle risposte non è in genere utile. I browser impostano comunemente le intestazioni di richiesta che impediscono la memorizzazione nella cache.

    Output caching (disponibile in .NET 7 e versioni successive) è un approccio migliore per le app dell'interfaccia utente. In questo scenario, la configurazione determina cosa memorizzare nella cache indipendentemente dalle intestazioni HTTP.

Per testare la memorizzazione nella cache delle risposte, usare Fiddler o un altro strumento in grado di impostare in modo esplicito le intestazioni della richiesta. L'impostazione esplicita delle intestazioni è preferibile per il test della memorizzazione nella cache. Per altre informazioni, vedere Risoluzione dei problemi relativi al middleware > di memorizzazione nella cache delle risposte.

Visualizzare o scaricare il codice di esempio (procedura per il download)

Memorizzazione nella cache delle risposte basata su HTTP

La specifica RFC 9111: Memorizzazione nella cache HTTP descrive il comportamento delle cache Internet. L'intestazione HTTP primaria usata per la memorizzazione nella cache è Cache-Control, che viene usata per specificare le direttive della cache. Le direttive controllano il comportamento di memorizzazione nella cache man mano che le richieste si spostano dai client ai server e le risposte si spostano di ritorno dai server ai client. Le richieste e le risposte passano attraverso server proxy e i server proxy devono essere conformi anche alla specifica http 1.1 di memorizzazione nella cache.

Le direttive comuni Cache-Control sono illustrate nella tabella seguente.

Direttiva Azione
pubblico Una cache può archiviare la risposta.
privato Una cache condivisa non deve archiviare la risposta. Una cache privata può archiviare e riutilizzare la risposta.
max-age Il client non accetta una risposta la cui età è maggiore del numero specificato di secondi. Esempi: max-age=60 (60 secondi), max-age=2592000 (un mese)
no-cache Nelle richieste: una cache non deve usare una risposta archiviata per soddisfare la richiesta. Il server di origine rigenera la risposta per il client e il middleware aggiorna la risposta archiviata nella cache.

Nelle risposte: la risposta non deve essere usata per una richiesta successiva senza convalida nel server di origine.
no-store Nelle richieste: una cache non deve archiviare la richiesta.

Nelle risposte: una cache non deve archiviare alcuna parte della risposta.

Altre intestazioni della cache che svolgono un ruolo nel caching sono mostrate nella tabella seguente.

Intestazione Funzione
Età Fornisce una stima della quantità di tempo in secondi dopo la generazione o la convalida della risposta nel server di origine.
Scade il Specifica l'ora dopo la quale la risposta viene considerata non aggiornata.
Pragma Esiste per garantire la compatibilità retroattiva delle cache HTTP 1.0 per l'impostazione no-cache del comportamento. Se l'intestazione Cache-Control è presente, l'intestazione Pragma viene ignorata.
Vary Specifica che una risposta memorizzata nella cache non deve essere inviata a meno che tutti i Vary campi di intestazione corrispondano sia nella richiesta originale della risposta memorizzata nella cache che nella nuova richiesta.

La memorizzazione nella cache basata su HTTP rispetta le direttive di Cache-Control della richiesta

La specifica RFC 9111: memorizzazione nella cache HTTP (sezione 5.2. Cache-Control) richiede una cache per rispettare un'intestazione valida Cache-Control inviata dal client. Un client può effettuare richieste con un no-cache valore di intestazione e forzare il server a generare una nuova risposta per ogni richiesta.

È consigliabile rispettare sempre le intestazioni delle richieste client Cache-Control se si considera l'obiettivo della memorizzazione nella cache HTTP. In base alla specifica ufficiale, la memorizzazione nella cache è destinata a ridurre la latenza e il sovraccarico di rete per soddisfare le richieste in una rete di client, proxy e server. Non è necessariamente un modo per controllare il carico in un server di origine.

Questo comportamento di memorizzazione nella cache non è controllato dallo sviluppatore quando si usa il middleware di memorizzazione nella cache della risposta perché il middleware è conforme alla specifica ufficiale della memorizzazione nella cache. .NET 7 e versioni successive include il supporto per la memorizzazione nella cache output per controllare meglio il carico del server. Per altre informazioni, vedere Cache di output.

Attributo ResponseCache

La classe ResponseCacheAttribute specifica i parametri necessari per impostare le intestazioni appropriate nella memorizzazione in cache delle risposte.

Avviso

Disabilitare la memorizzazione nella cache per il contenuto che contiene informazioni per i client autenticati. La memorizzazione nella cache deve essere abilitata solo per quei contenuti che non cambiano in base all'identità di un utente o al fatto che un utente sia connesso.

La VaryByQueryKeys proprietà varia la risposta archiviata in base ai valori dell'elenco specificato di chiavi di query. Quando viene fornito un singolo valore dell'asterisco jolly (*), il middleware varia le risposte in base a tutti i parametri della stringa di query della richiesta.

Per impostare la proprietà, è necessario abilitare il middleware di memorizzazione nella cache delle VaryByQueryKeys risposte. In caso contrario, viene generata un'eccezione di runtime. Non esiste un'intestazione HTTP corrispondente per la VaryByQueryKeys proprietà . La proprietà è una funzionalità HTTP gestita dal Middleware di Cache delle Risposte. Affinché il middleware gestisca una risposta memorizzata nella cache, la stringa di query e il valore della stringa di query devono corrispondere a una richiesta precedente. Si consideri, ad esempio, la sequenza di richieste e i risultati illustrati nella tabella seguente:

Richiedi Restituito da
http://example.com?key1=value1 Servidor
http://example.com?key1=value1 Middleware
http://example.com?key1=NewValue Servidor

Il server restituisce la prima richiesta e il middleware memorizza nella cache la richiesta. Il middleware restituisce la seconda richiesta perché la stringa di query corrisponde alla richiesta precedente (prima). La terza richiesta non si trova nella cache middleware perché il valore della stringa di query non corrisponde a una richiesta precedente.

La classe ResponseCacheAttribute viene usata per configurare e creare un Microsoft.AspNetCore.Mvc.Internal.ResponseCacheFilter tramite l'interfaccia IFilterFactory. ResponseCacheFilter si occupa dell'aggiornamento delle intestazioni HTTP pertinenti e delle funzionalità della risposta. Filtro:

  • Rimuove tutte le intestazioni esistenti per Vary, Cache-Control e Pragma.
  • Scrive le intestazioni appropriate in base alle proprietà impostate in ResponseCacheAttribute.
  • Aggiorna la funzionalità HTTP di memorizzazione nella cache delle risposte se la VaryByQueryKeys proprietà è impostata.

Variabile intestazione

Questa intestazione viene scritta solo quando la VaryByHeader proprietà è impostata. La proprietà è impostata al valore della proprietà Vary. Nell'esempio seguente viene utilizzata la VaryByHeader proprietà :

[ApiController]
public class TimeController : ControllerBase
{
    [Route("api/[controller]")]
    [HttpGet]
    [ResponseCache(VaryByHeader = "User-Agent", Duration = 30)]
    public ContentResult GetTime() => Content(
                      DateTime.Now.Millisecond.ToString());

Visualizza le intestazioni di risposta con Fiddler o un altro strumento. Le intestazioni delle risposte includono:

Cache-Control: public,max-age=30
Vary: User-Agent

Il codice precedente richiede l'aggiunta dei servizi Middleware di memorizzazione nella cache delle risposte tramite il metodo AddResponseCaching alla raccolta di servizi. Il codice configura l'app per l'uso del middleware con il UseResponseCaching metodo di estensione.

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddControllers();
builder.Services.AddResponseCaching();

var app = builder.Build();

app.UseHttpsRedirection();

// UseCors must be called before UseResponseCaching
//app.UseCors();

app.UseResponseCaching();

app.UseAuthorization();

app.MapControllers();

app.Run();

Proprietà NoStore e Location.None

La NoStore proprietà esegue l'override della maggior parte delle altre proprietà. Quando questa proprietà è impostata su true, l'intestazione Cache-Control è impostata su no-store. Se la proprietà Location è impostata su None:

  • L'intestazione Cache-Control è impostata su no-store,no-cache.
  • L'intestazione Pragma è impostata su no-cache.

Se la NoStore proprietà è impostata su false e la Location proprietà è impostata su None, le Cache-Control intestazioni e Pragma vengono impostate su no-cache.

La NoStore proprietà è in genere impostata su true per le pagine di errore. Il codice seguente genera intestazioni di risposta che indicano al client di non archiviare la risposta.

[Route("api/[controller]/ticks")]
[HttpGet]
[ResponseCache(Location = ResponseCacheLocation.None, NoStore = true)]
public ContentResult GetTimeTicks() => Content(
                  DateTime.Now.Ticks.ToString());

Il codice precedente include le intestazioni seguenti nella risposta:

Cache-Control: no-store,no-cache
Pragma: no-cache

Per applicare il ResponseCacheAttribute a tutte le risposte del controller MVC o Razor delle Pagine dell'app, aggiungere l'attributo con un filtro MVC o un Razor filtro Pages.

In un'app MVC aggiungere il codice seguente:

builder.Services.AddControllersWithViews().AddMvcOptions(options => 
    options.Filters.Add(
        new ResponseCacheAttribute
        {
            NoStore = true, 
            Location = ResponseCacheLocation.None
        }));

Per un approccio applicabile alle app Razor Pages, vedere il problema dotnet/aspnetcore su GitHub #18890 - . L'aggiunta di ResponseCacheAttribute all'elenco dei filtri globali MVC non si applica alle Razor Pages. L'esempio di commento nel problema si applica alle app ASP.NET Core che precedono il rilascio delle API Minimal (ASP.NET Core versione 6.0). Per le app destinate alla versione 6.0 e successive, modificare la registrazione del servizio usata nell'esempio in builder.Services.AddSingleton... nel file Program.cs .

Proprietà Location e Duration

Per abilitare la memorizzazione nella cache, la Duration proprietà deve essere impostata su un valore positivo e Location deve essere Any (impostazione predefinita) o Client. Il framework imposta l'intestazione Cache-Control sul valore della posizione seguito dall'elemento max-age della risposta.

Le Location opzioni di proprietà di Any e Client si traducono rispettivamente nei Cache-Control valori di intestazione di public e private. Come indicato nella sezione NoStore e Location.None, l'impostazione della proprietà Location su None imposta sia le intestazioni Cache-Control che Pragma su no-cache.

L'impostazione Location.Any della proprietà (Cache-Control impostata su public) indica che il client o qualsiasi proxy intermedio può memorizzare il valore nella cache, incluso il Middleware di caching della risposta.

L'impostazione Location.Client della proprietà (Cache-Control impostata su private) indica che solo il client può memorizzare nella cache il valore. Nessuna cache intermedia deve salvare nella cache il valore, incluso Response Caching Middleware.

Le intestazioni di controllo della cache forniscono indicazioni ai client e ai proxy intermedi su quando e come memorizzare nella cache le risposte. Non esiste alcuna garanzia che i client e i proxy rispettano la specifica RFC 9111: memorizzazione nella cache HTTP . Il middleware di memorizzazione nella cache delle risposte segue sempre le regole di memorizzazione nella cache disposte in base alla specifica.

Nell'esempio seguente vengono illustrate le intestazioni generate impostando la Duration proprietà e lasciando il valore predefinito Location della proprietà:

[Route("api/[controller]/ms")]
[HttpGet]
[ResponseCache(Duration = 10, Location = ResponseCacheLocation.Any, NoStore = false)]
public ContentResult GetTimeMS() => Content(
                  DateTime.Now.Millisecond.ToString());

Il codice precedente include nella risposta le seguenti intestazioni:

Cache-Control: public,max-age=10

Profili cache

Invece di duplicare le impostazioni della cache delle risposte in molti attributi di azione del controller, i profili di cache possono essere configurati come opzioni durante la configurazione di pagine MVC o Razor. I valori trovati in un profilo di cache a cui si fa riferimento vengono usati come valori predefiniti da ResponseCacheAttribute. Tutte le proprietà specificate nell'attributo sostituiscono i valori del profilo della cache a cui si fa riferimento.

L'esempio seguente mostra un profilo di cache di 30 secondi:

using Microsoft.AspNetCore.Mvc;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddResponseCaching();
builder.Services.AddControllers(options =>
{
    options.CacheProfiles.Add("Default30",
        new CacheProfile()
        {
            Duration = 30
        });
});

var app = builder.Build();

app.UseHttpsRedirection();

// UseCors must be called before UseResponseCaching
//app.UseCors();

app.UseResponseCaching();

app.UseAuthorization();

app.MapControllers();

app.Run();

Il codice seguente fa riferimento al profilo della Default30 cache:

[ApiController]
[ResponseCache(CacheProfileName = "Default30")]
public class Time2Controller : ControllerBase
{
    [Route("api/[controller]")]
    [HttpGet]
    public ContentResult GetTime() => Content(
                      DateTime.Now.Millisecond.ToString());

    [Route("api/[controller]/ticks")]
    [HttpGet]
    public ContentResult GetTimeTicks() => Content(
                      DateTime.Now.Ticks.ToString());
}

La risposta dell'intestazione risultante dal profilo di cache Default30 include:

Cache-Control: public,max-age=30

È possibile applicare l'attributo [ResponseCache] alle pagine, ai controller MVC e ai metodi di azione MVC.

In Razor Pages non è possibile applicare attributi ai metodi del gestore perché i browser usati con le app dell'interfaccia utente impediscono la memorizzazione nella cache delle risposte. In un metodo di azione MVC gli attributi a livello di metodo sostituiscono le impostazioni specificate negli attributi a livello di classe.

Il codice seguente applica l'attributo [ResponseCache] a livello di controller e metodo:

[ApiController]
[ResponseCache(VaryByHeader = "User-Agent", Duration = 30)]
public class Time4Controller : ControllerBase
{
    [Route("api/[controller]")]
    [HttpGet]
    public ContentResult GetTime() => Content(
                      DateTime.Now.Millisecond.ToString());

    [Route("api/[controller]/ticks")]
    [HttpGet]
    public ContentResult GetTimeTicks() => Content(
                  DateTime.Now.Ticks.ToString());

    [Route("api/[controller]/ms")]
    [HttpGet]
    [ResponseCache(Duration = 10, Location = ResponseCacheLocation.Any, NoStore = false)]
    public ContentResult GetTimeMS() => Content(
                      DateTime.Now.Millisecond.ToString());
}

Visualizzare o scaricare il codice di esempio (procedura per il download)

La memorizzazione nella cache delle risposte riduce il numero di richieste eseguite da un client o un proxy a un server Web. La memorizzazione nella cache delle risposte riduce anche la quantità di lavoro eseguita dal server Web per generare una risposta. La memorizzazione nella cache delle risposte è controllata dalle intestazioni che specificano la modalità di memorizzazione nella cache delle risposte da parte di client, proxy e middleware.

Partecipa all'impostazione [ResponseCache] delle intestazioni di memorizzazione nella cache delle risposte. I client e i proxy intermedi devono rispettare le intestazioni per la memorizzazione nella cache delle risposte in RFC 9111: memorizzazione nella cache HTTP.

Per la memorizzazione nella cache lato server che segue la specifica HTTP 1.1, usare il middleware di caching delle risposte. Il middleware può utilizzare le proprietà [ResponseCache] per impostare le intestazioni di caching lato server.

Memorizzazione nella cache delle risposte basata su HTTP

RFC 9111: la memorizzazione nella cache HTTP descrive il comportamento delle cache Internet. L'intestazione HTTP primaria usata per la memorizzazione nella cache è Cache-Control, che viene usata per specificare le direttive della cache. Le direttive controllano il comportamento della cache mentre le richieste vengono trasmesse dai client ai server e le risposte vengono inoltrate dai server ai client. Le richieste e le risposte passano attraverso server proxy e i server proxy devono essere conformi anche alla specifica http 1.1 di memorizzazione nella cache.

Le direttive comuni Cache-Control sono illustrate nella tabella seguente.

Direttiva Azione
pubblico Una cache può archiviare la risposta.
privato La risposta non deve essere archiviata da una cache condivisa. Una cache privata può archiviare e riutilizzare la risposta.
max-age Il client non accetta una risposta la cui età è maggiore del numero specificato di secondi. Esempi: max-age=60 (60 secondi), max-age=2592000 (1 mese)
no-cache Nelle richieste: una cache non deve usare una risposta archiviata per soddisfare la richiesta. Il server di origine rigenera la risposta per il client e il middleware aggiorna la risposta archiviata nella cache.

Nelle risposte: la risposta non deve essere usata per una richiesta successiva senza convalida nel server di origine.
no-store Nelle richieste: una cache non deve archiviare la richiesta.

Nelle risposte: una cache non deve archiviare alcuna parte della risposta.

Altre intestazioni della cache che svolgono un ruolo nel caching sono mostrate nella tabella seguente.

Intestazione Funzione
Età Stima della quantità di tempo in secondi dopo la generazione o la convalida della risposta nel server di origine.
Scade il Tempo dopo il quale la risposta viene considerata non aggiornata.
Pragma Esiste per garantire la retrocompatibilità con le cache HTTP/1.0 per l'impostazione no-cache del comportamento. Se l'intestazione Cache-Control è presente, l'intestazione Pragma viene ignorata.
Vary Specifica che una risposta memorizzata nella cache non deve essere inviata a meno che tutti i Vary campi di intestazione corrispondano sia nella richiesta originale della risposta memorizzata nella cache che nella nuova richiesta.

La memorizzazione nella cache basata su HTTP rispetta le direttive di Cache-Control della richiesta

RFC 9111: Memorizzazione nella cache HTTP (Sezione 5.2: Cache-Control) richiede che una cache rispetti un'intestazione valida Cache-Control inviata dal client. Un client può effettuare richieste con un no-cache valore di intestazione e forzare il server a generare una nuova risposta per ogni richiesta.

È consigliabile rispettare sempre le intestazioni delle richieste client Cache-Control se si considera l'obiettivo della memorizzazione nella cache HTTP. In base alla specifica ufficiale, la memorizzazione nella cache è destinata a ridurre la latenza e il sovraccarico di rete per soddisfare le richieste in una rete di client, proxy e server. Non è necessariamente un modo per controllare il carico in un server di origine.

Questo comportamento di memorizzazione nella cache non è controllato dallo sviluppatore quando si usa il middleware di memorizzazione nella cache della risposta perché il middleware è conforme alla specifica ufficiale della memorizzazione nella cache. Il supporto per la memorizzazione nella cache di output per controllare meglio il carico del server è una proposta di progettazione per una versione futura di ASP.NET Core. Per altre informazioni, vedere Aggiungere il supporto per la memorizzazione nella cache di output (dotnet/aspnetcore #27387)..

Altre tecnologie di memorizzazione nella cache in ASP.NET Core

Memorizzazione nella cache in memoria

La memorizzazione nella cache in memoria usa la memoria del server per archiviare i dati memorizzati nella cache. Questo tipo di memorizzazione nella cache è adatto per un singolo server o più server che usano l'affinità di sessione. L'affinità di sessione è nota anche come sticky sessions. L'affinità di sessione indica che le richieste da un client vengono sempre instradate allo stesso server per l'elaborazione.

Per ulteriori informazioni, vedere Cache in memoria in ASP.NET Core e risolvere i problemi di affinità di sessione nel gateway delle applicazioni Azure.

Cache distribuita

Usare una cache distribuita per archiviare i dati in memoria quando l'app è ospitata in un cloud o in una server farm. La cache viene condivisa tra i server che elaborano le richieste. Un client può inviare una richiesta gestita da qualsiasi server nel gruppo se sono disponibili dati memorizzati nella cache per il client. ASP.NET Core funziona con le cache distribuite di SQL Server, Redis, Postgres e NCache .

Per altre informazioni, vedere Memorizzazione nella cache distribuita in ASP.NET Core.

Helper per tag di cache

Memorizza nella cache il contenuto di una vista MVC o della Pagina con il Tag Helper della cache. L'helper Cache Tag utilizza il caching in memoria per archiviare i dati.

Per altre informazioni, vedere Helper tag cache in ASP.NET Core MVC.

Tag helper di cache distribuita

Memorizza nella cache il contenuto di una vista MVC o di una pagina Razor in scenari di cloud distribuito o web farm con il Tag Helper della cache distribuita. L'helper tag della cache distribuita usa SQL Server, Redis o NCache per archiviare i dati.

Per altre informazioni, vedere Distributed Cache Tag Helper in ASP.NET Core.

Attributo ResponseCache

ResponseCacheAttribute Specifica i parametri necessari per impostare le intestazioni appropriate nel caching delle risposte.

Avviso

Disabilitare la memorizzazione nella cache per il contenuto che contiene informazioni per i client autenticati. La memorizzazione nella cache deve essere abilitata solo per quei contenuti che non cambiano in base all'identità di un utente o al fatto che un utente sia connesso.

VaryByQueryKeys varia la risposta archiviata in base ai valori dell'elenco specificato di chiavi di query. Quando viene specificato un singolo valore di , il middleware varia le risposte in base a tutti i parametri della stringa di * query di richiesta.

Il middleware di memorizzazione nella cache delle risposte deve essere abilitato per impostare la proprietà VaryByQueryKeys. In caso contrario, viene generata un'eccezione di runtime. Non esiste un'intestazione HTTP corrispondente per la VaryByQueryKeys proprietà . La proprietà è una funzionalità HTTP gestita dal middleware di caching delle risposte. Affinché il middleware gestisca una risposta memorizzata nella cache, la stringa di query e il valore della stringa di query devono corrispondere a una richiesta precedente. Si consideri, ad esempio, la sequenza di richieste e i risultati illustrati nella tabella seguente.

Richiedi Risultato
http://example.com?key1=value1 Restituito dal server.
http://example.com?key1=value1 Restituito dal middleware.
http://example.com?key1=value2 Ritorno dal server.

La prima richiesta viene restituita dal server e memorizzata nella cache nel middleware. La seconda richiesta viene restituita dal middleware perché la stringa di query corrisponde alla richiesta precedente. La terza richiesta non si trova nella cache middleware perché il valore della stringa di query non corrisponde a una richiesta precedente.

ResponseCacheAttribute viene usato per configurare e creare (tramite IFilterFactory) un Microsoft.AspNetCore.Mvc.Internal.ResponseCacheFilter. ResponseCacheFilter esegue il lavoro di aggiornamento delle intestazioni appropriate e delle funzionalità HTTP della risposta. Filtro:

  • Rimuove tutte le intestazioni esistenti per Vary, Cache-Control e Pragma.
  • Scrive le intestazioni appropriate in base alle proprietà definite in ResponseCacheAttribute.
  • Aggiorna la funzionalità HTTP per la memorizzazione nella cache delle risposte, se VaryByQueryKeys impostata.

Variare

Questa intestazione viene scritta solo quando la VaryByHeader proprietà è impostata. La proprietà è impostata sul valore della proprietà Vary. Nell'esempio seguente viene utilizzata la VaryByHeader proprietà :

[ResponseCache(VaryByHeader = "User-Agent", Duration = 30)]
public class Cache1Model : PageModel
{

Utilizzando l'applicazione di esempio, visualizza le intestazioni di risposta con gli strumenti di rete del browser. Le intestazioni di risposta seguenti vengono inviate con la risposta della pagina Cache1:

Cache-Control: public,max-age=30
Vary: User-Agent

NoStore e Location.None

NoStore sovrascrive la maggior parte delle altre proprietà. Quando questa proprietà è impostata su true, l'intestazione Cache-Control è impostata su no-store. Se Location è impostato su None:

  • Cache-Control è impostato su no-store,no-cache.
  • Pragma è impostato su no-cache.

Se NoStore è false e Location è None, Cache-Control, e Pragma sono impostati su no-cache.

NoStore viene in genere impostato su true per le pagine di errore. La pagina Cache2 nell'app di esempio produce intestazioni di risposta che indicano al client di non archiviare la risposta.

[ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
public class Cache2Model : PageModel
{

L'app di esempio restituisce la pagina Cache2 con le intestazioni seguenti:

Cache-Control: no-store,no-cache
Pragma: no-cache

Per applicare ResponseCacheAttribute a tutte le risposte del controller MVC o delle pagine Razor dell'app, aggiungilo con un filtro MVC o un filtro Razor Pages.

In un'applicazione MVC:

services.AddMvc().AddMvcOptions(options => 
    options.Filters.Add(
        new ResponseCacheAttribute
        {
            NoStore = true, 
            Location = ResponseCacheLocation.None
        }));

Per un approccio applicabile alle Razor app Pages, vedere Aggiunta ResponseCacheAttribute all'elenco di filtri globali MVC non si applica alle Razor Pages (dotnet/aspnetcore #18890).

Posizione e durata

Per abilitare la memorizzazione nella cache, Duration deve essere impostato su un valore positivo e Location deve essere Any (impostazione predefinita) o Client. Il framework imposta l'intestazione Cache-Control al valore di location seguito dal componente max-age della risposta.

LocationLe opzioni di Any e Client si traducono rispettivamente nei valori di intestazione di public e private. Come indicato nella sezione NoStore e Location.None, l'impostazione di Location su None imposta sia le intestazioni Cache-Control che Pragma su no-cache.

Location.Any (Cache-Control impostato su public) indica che il client o qualsiasi proxy intermedio può memorizzare nella cache il valore, incluso il Middleware di Caching della Risposta.

Location.Client (Cache-Control impostato su private) indica che solo il client può memorizzare nella cache il valore. Nessuna cache intermedia deve cachare il valore, incluso il Middleware di cache delle risposte.

Le intestazioni di controllo della cache forniscono semplicemente indicazioni ai client e ai proxy intermedi quando e come memorizzare nella cache le risposte. Non c'è garanzia che i client e i proxy rispettano RFC 9111: memorizzazione nella cache HTTP. Il middleware di memorizzazione nella cache delle risposte segue sempre le regole di memorizzazione nella cache disposte in base alla specifica.

L'esempio seguente mostra il modello di pagina Cache3 dell'app di esempio e le intestazioni prodotte impostando Duration e lasciando il valore predefinito Location :

[ResponseCache(Duration = 10, Location = ResponseCacheLocation.Any, NoStore = false)]
public class Cache3Model : PageModel
{

L'app di esempio restituisce la pagina Cache3 con l'intestazione seguente:

Cache-Control: public,max-age=10

Profili cache

Anziché duplicare le impostazioni della cache della risposta in molti attributi di azione del controller, i profili della cache possono essere configurati come opzioni durante la configurazione delle pagine MVC/Razor in Startup.ConfigureServices. I valori trovati in un profilo di cache a cui si fa riferimento vengono usati come valori predefiniti da ResponseCacheAttribute e vengono sottoposti a override da qualsiasi proprietà specificata nell'attributo .

Configurare un profilo di cache. L'esempio seguente mostra un profilo di cache di 30 secondi nell'applicazione di esempio Startup.ConfigureServices.

public void ConfigureServices(IServiceCollection services)
{
    services.AddRazorPages();
    services.AddMvc(options =>
    {
        options.CacheProfiles.Add("Default30",
            new CacheProfile()
            {
                Duration = 30
            });
    });
}

Il modello di pagina Cache4 dell'app di esempio fa riferimento al profilo della Default30 cache:

[ResponseCache(CacheProfileName = "Default30")]
public class Cache4Model : PageModel
{

L'oggetto ResponseCacheAttribute può essere applicato a:

  • Razor Pagine: gli attributi non possono essere applicati ai metodi del gestore.
  • Controller MVC
  • Metodi di azione MVC: gli attributi a livello di metodo sostituiscono le impostazioni specificate negli attributi a livello di classe.

Intestazione risultante applicata alla risposta della pagina Cache4 dal profilo della Default30 cache:

Cache-Control: public,max-age=30

Risorse aggiuntive