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 in RFC 9111: memorizzazione nella cache HTTP.
Per la memorizzazione nella cache lato server che segue la specifica http 1.1 di memorizzazione nella cache, usare il middleware di memorizzazione nella cache delle risposte. Il middleware può usare le proprietà per influenzare il ResponseCacheAttribute comportamento di memorizzazione nella cache lato server.
Middleware di memorizzazione nella cache della risposta:
Abilita la memorizzazione nella cache delle risposte del server in base alle intestazioni della cache HTTP. Implementa la semantica di memorizzazione nella cache HTTP standard. Memorizza nella cache le intestazioni della cache HTTP come i proxy.
In genere non è utile per le app dell'interfaccia utente, ad Razor esempio Pagine, perché i browser impostano in genere intestazioni di richiesta che impediscono la memorizzazione nella cache.
La memorizzazione nella cache di output, disponibile in ASP.NET Core 7.0 e versioni successive, offre vantaggi alle app dell'interfaccia utente. Con la memorizzazione nella cache dell'output, la configurazione decide cosa deve essere memorizzato nella cache indipendentemente da intestazioni HTTP.
Può essere utile per le richieste API GET o HEAD pubbliche dai client in cui vengono soddisfatte le condizioni per la memorizzazione nella cache .
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 ulteriori informazioni, vedere Risoluzione dei problemi.
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 di memorizzazione nella cache come richieste fanno il loro modo da client a server e come risposte fanno il loro modo 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.
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.
Esiste per la compatibilità con le versioni precedenti con le cache HTTP/1.0 per l'impostazione no-cache del comportamento. Se l'intestazione Cache-Control è presente, l'intestazione Pragma viene ignorata.
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 della richiesta
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. Il supporto per la memorizzazione nella cache dell'output per controllare meglio il carico del server è stato aggiunto in .NET 7. Per altre informazioni, vedere Memorizzazione nella cache dell'output.
Attributo ResponseCache
ResponseCacheAttribute Specifica i parametri necessari per impostare le intestazioni appropriate nella memorizzazione nella 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.
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.
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 memorizzazione nella 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
Server
http://example.com?key1=value1
Middleware
http://example.com?key1=NewValue
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.
viene ResponseCacheAttribute usato per configurare e creare (tramite IFilterFactory) un oggetto Microsoft.AspNetCore.Mvc.Internal.ResponseCacheFilter.
ResponseCacheFilter esegue il lavoro di aggiornamento delle intestazioni e delle funzionalità HTTP appropriate della risposta. Filtro:
Rimuove tutte le intestazioni esistenti per Vary, Cache-Controle Pragma.
Scrive le intestazioni appropriate in base alle proprietà impostate in ResponseCacheAttribute.
Aggiorna la funzionalità HTTP per la memorizzazione nella cache delle risposte, se VaryByQueryKeys impostata.
Variabile
Questa intestazione viene scritta solo quando la VaryByHeader proprietà è impostata. Proprietà impostata sul Vary valore della proprietà. 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());
Visualizzare le intestazioni di risposta con Fiddler o un altro strumento. Le intestazioni di risposta 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 alla raccolta di servizi AddResponseCaching e 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();
NoStore e Location.None
NoStore esegue l'override della 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 è e false è LocationNone , Cache-Controle Pragma sono impostati su no-cache.
NoStore viene in genere impostato su true per le pagine di errore. Di seguito vengono restituite intestazioni di risposta che indicano al client di non archiviare la risposta.
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 sul valore della posizione seguito dall'oggetto max-age della risposta.
LocationLe opzioni di Any e Client traducono rispettivamente in Cache-Control valori di intestazione di public e private. Come indicato nella sezione NoStore e Location.None, l'impostazione Location su None imposta le intestazioni e Cache-ControlPragma 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 memorizzazione nella cache della risposta.
Location.Client (Cache-Control impostato su private) indica che solo il client può memorizzare nella cache il valore. Nessuna cache intermedia deve memorizzare nella cache il valore, incluso il middleware di memorizzazione nella cache delle risposte.
Le intestazioni di controllo della cache forniscono 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 le intestazioni prodotte impostando Duration e lasciando il valore predefinito Location :
Il codice precedente include le intestazioni seguenti nella risposta:
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 cache possono essere configurati come opzioni durante la configurazione di MVC/Razor Pages. 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 .
L'esempio seguente mostra un profilo 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 della Default30 cache include:
Razor Pagine: gli attributi non possono essere applicati ai metodi del gestore. I browser usati con le app dell'interfaccia utente impediscono la memorizzazione nella cache delle risposte.
Controller MVC.
Metodi 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());
}
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 di memorizzazione nella cache, usare il middleware di memorizzazione nella cache delle risposte. Il middleware può usare le [ResponseCache] proprietà per impostare le intestazioni di memorizzazione nella cache 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 di memorizzazione nella cache come richieste fanno il loro modo da client a server e come risposte fanno il loro modo 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.
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.
Esiste per la compatibilità con le versioni precedenti con le cache HTTP/1.0 per l'impostazione no-cache del comportamento. Se l'intestazione Cache-Control è presente, l'intestazione Pragma viene ignorata.
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 della richiesta
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. 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 sessioni permanenti. L'affinità di sessione indica che le richieste da un client vengono sempre instradate allo stesso server per l'elaborazione.
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 e NCache .
Memorizzare nella cache il contenuto da una visualizzazione MVC o Razor da una pagina con l'helper tag della cache. L'helper tag cache usa la memorizzazione nella cache in memoria per archiviare i dati.
Memorizzare nella cache il contenuto da una visualizzazione MVC o Razor da una pagina in scenari cloud o web farm distribuiti con l'helper tag cache distribuita. L'helper tag della cache distribuita usa SQL Server, Redis o NCache per archiviare i dati.
ResponseCacheAttribute Specifica i parametri necessari per impostare le intestazioni appropriate nella memorizzazione nella 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 il contenuto che non cambia in base all'identità di un utente o se un utente è collegato.
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.
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 memorizzazione nella 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
Risultato
http://example.com?key1=value1
Restituito dal server.
http://example.com?key1=value1
Restituito dal middleware.
http://example.com?key1=value2
Restituito 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.
viene ResponseCacheAttribute usato per configurare e creare (tramite IFilterFactory) un oggetto Microsoft.AspNetCore.Mvc.Internal.ResponseCacheFilter.
ResponseCacheFilter esegue il lavoro di aggiornamento delle intestazioni e delle funzionalità HTTP appropriate della risposta. Filtro:
Rimuove tutte le intestazioni esistenti per Vary, Cache-Controle Pragma.
Scrive le intestazioni appropriate in base alle proprietà impostate in ResponseCacheAttribute.
Aggiorna la funzionalità HTTP per la memorizzazione nella cache delle risposte, se VaryByQueryKeys impostata.
Variabile
Questa intestazione viene scritta solo quando la VaryByHeader proprietà è impostata. Proprietà impostata sul Vary valore della proprietà. Nell'esempio seguente viene utilizzata la VaryByHeader proprietà :
[ResponseCache(VaryByHeader = "User-Agent", Duration = 30)]
public class Cache1Model : PageModel
{
Usando l'app di esempio, visualizzare 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 esegue l'override della 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 è e false è LocationNone , Cache-Controle 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:
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 sul valore della posizione seguito dall'oggetto max-age della risposta.
LocationLe opzioni di Any e Client traducono rispettivamente in Cache-Control valori di intestazione di public e private. Come indicato nella sezione NoStore e Location.None, l'impostazione Location su None imposta le intestazioni e Cache-ControlPragma 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 memorizzazione nella cache della risposta.
Location.Client (Cache-Control impostato su private) indica che solo il client può memorizzare nella cache il valore. Nessuna cache intermedia deve memorizzare nella cache il valore, incluso il middleware di memorizzazione nella 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 delle risposte in molti attributi di azione del controller, i profili della cache possono essere configurati come opzioni durante la configurazione di MVC/Razor Pages 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'app di Startup.ConfigureServicesesempio:
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'origine di questo contenuto è disponibile in GitHub, in cui è anche possibile creare ed esaminare i problemi e le richieste pull. Per ulteriori informazioni, vedere la guida per i collaboratori.
Feedback su ASP.NET Core
ASP.NET Core è un progetto di open source. Selezionare un collegamento per fornire feedback:
In questo modulo verranno fornite informazioni sulle cache in un'app nativa del cloud .NET Aspire e su come usarle per ottimizzare le prestazioni dei microservizi.
Informazioni su come usare una cache distribuita ASP.NET Core per migliorare le prestazioni e la scalabilità delle app, in particolare in un ambiente cloud o server farm.