Zwischenspeichern von Antworten in ASP.NET Core

Von Rick Anderson und Kirk Larkin

Das Zwischenspeichern von Antworten reduziert die Anzahl von Anforderungen, die ein Client oder Proxy an einen Webserver sendet. Das Zwischenspeichern von Antworten reduziert auch den Aufwand zum Generieren einer Antwort durch den Webserver. Das Zwischenspeichern von Antworten wird in Headern festgelegt.

Das ResponseCache-Attribut legt die Header für das Zwischenspeichern von Antworten fest. Clients und zwischengeschaltete Proxys sollten die Header für das Zwischenspeichern von Antworten gemäß der RFC 9111: HTTP Caching Spezifikation beachten.

Zum serverseitigen Zwischenspeichern entsprechend der Spezifikation „HTTP 1.1 Caching“ verwenden Sie Middleware zum Zwischenspeichern von Antworten. Die Middleware kann die ResponseCacheAttribute-Eigenschaften verwenden, um das Verhalten beim serverseitigen Zwischenspeichern zu beeinflussen.

Die Antwort-Caching-Middleware ermöglicht das Zwischenspeichern von Serverantworten basierend auf HTTP-Cache-Control-Headern.

  • Das Zwischenspeicherungsverhalten implementiert standardmäßige HTTP-Zwischenspeicherungsemantik.

  • Das Zwischenspeichern basiert auf HTTP-Cacheheadern, die der von Proxys verwendeten Methode ähneln.

  • Diese Form der Zwischenspeicherung ist nützlich für öffentliche GET- oder HEAD-API-Anforderungen von Clients, bei denen die Bedingungen für die Zwischenspeicherung erfüllt sind.

  • Für UI-Apps wie Razor Seiten ist das Zwischenspeichern von Antworten in der Regel nicht von Vorteil. Browser legen häufig Anforderungsheader fest, die das Zwischenspeichern verhindern.

    Output caching (verfügbar in .NET 7 und höher) ist ein besserer Ansatz für UI-Apps. In diesem Szenario bestimmt die Konfiguration, was unabhängig von HTTP-Headern zwischengespeichert werden soll.

Um das Zwischenspeichern von Antworten zu testen, verwenden Sie Fiddler oder ein anderes Tool, das Anforderungsheader explizit festlegen kann. Beim Testen der Zwischenspeicherung wird das explizite Festlegen von Headern bevorzugt. Weitere Informationen finden Sie unter "Problembehandlung bei der Zwischenspeicherung von Reaktions-Middleware > ".

Anzeigen oder Herunterladen von Beispielcode (Vorgehensweise zum Herunterladen)

HTTP-basiertes Zwischenspeichern von Antworten

Die RFC 9111: HTTP Caching-Spezifikation beschreibt, wie sich Internetcaches verhalten sollten. Der für die Zwischenspeicherung verwendete primäre HTTP-Header ist Cache-Control – damit werden Anweisungen für den Cache angegeben. Die Direktiven steuern das Zwischenspeicherungsverhalten, wenn Anforderungen von Clients zu Servern erfolgen und Antworten von Servern zurück zu Clients wechseln. Anforderungen und Antworten werden über Proxyserver übertragen, und auch die Proxyserver müssen die HTTP 1.1 Caching-Spezifikation erfüllen.

Die folgende Tabelle zeigt gängige Cache-Control-Anweisungen.

Directive Action
public Ein Cache kann die Antwort speichern.
private Ein freigegebener Cache darf die Antwort nicht speichern. Ein privater Cache kann die Antwort speichern und wiederverwenden.
max-age Der Client akzeptiert keine Antwort, deren Alter größer ist als die angegebene Anzahl von Sekunden. Beispiele: max-age=60 (60 Sekunden), max-age=2592000 (ein Monat)
no-cache Bei Anforderungen: Ein Cache darf keine gespeicherte Antwort verwenden, um die Anforderung zu erfüllen. Der Ursprungsserver generiert die Antwort für den Client neu, und die Middleware aktualisiert die gespeicherte Antwort in ihrem Cache.

Bei Antworten: Die Antwort darf ohne Validierung auf dem Ursprungsserver nicht für eine nachfolgende Anforderung verwendet werden.
no-store Bei Anforderungen: Die Anforderung darf nicht in einem Cache gespeichert werden.

Bei Antworten: Kein Teil der Antwort darf in einem Cache gespeichert werden.

Die folgende Tabelle führt weitere Cacheheader auf, die beim Zwischenspeichern eine Rolle spielen.

Header Function
Age Stellt eine Schätzung der Zeitspanne in Sekunden bereit, seit die Antwort generiert oder erfolgreich auf dem Ursprungsserver überprüft wurde.
Expires Gibt die Zeit an, nach der die Antwort als veraltet betrachtet wird.
Pragma Besteht aus Gründen der Abwärtskompatibilität mit HTTP 1.0 Caches zum Festlegen des no-cache-Verhaltens. Wenn der Cache-Control-Header vorhanden ist, wird der Pragma-Header ignoriert.
Vary Gibt an, dass eine zwischengespeicherte Antwort nur gesendet werden darf, wenn alle Vary-Headerfelder sowohl in der ursprünglichen als auch in der neuen Anforderung der zwischengespeicherten Antwort übereinstimmen.

HTTP-basierte Zwischenspeicherung berücksichtigt Cache-Control-Anweisungen der Anforderung

Die RFC 9111: HTTP Caching -Spezifikation (Abschnitt 5.2. Cache-Control) erfordert einen Cache, um einen gültigen Cache-Control Header zu berücksichtigen, der vom Client gesendet wird. Ein Client kann Anforderungen mit dem Headerwert no-cache senden und den Server zwingen, für jede Anforderung eine neue Antwort zu generieren.

In Anbetracht des Ziels der HTTP-Zwischenspeicherung ist es sinnvoll, Cache-Control-Anforderungsheader immer zu berücksichtigen. Gemäß der offiziellen Spezifikation soll das Zwischenspeichern die Latenz und den Netzwerkoverhead beim Verarbeiten von Anforderungen in einem Netzwerk aus Clients, Proxys und Servern reduzieren. Es ist nicht unbedingt eine Möglichkeit, die Last auf einem Ursprungsserver zu steuern.

Entwickler*innen können dieses Verhalten der Zwischenspeicherung bei Verwendung der Middleware zum Zwischenspeichern von Antworten nicht steuern, da die Middleware die offizielle Spezifikation für die Zwischenspeicherung einhält. .NET 7 und höher bietet Unterstützung für output caching zur besseren Steuerung der Serverlast. Weitere Informationen finden Sie unter Ausgabezwischenspeicherung.

ResponseCache-Attribut

Die ResponseCacheAttribute Klasse gibt die Parameter an, die zum Festlegen geeigneter Header im Antwortzwischenspeicher erforderlich sind.

Warning

Deaktivieren Sie die Zwischenspeicherung für Inhalte, die Informationen für authentifizierte Clients enthalten. Das Zwischenspeichern sollte nur für Inhalte aktiviert werden, die sich nicht basierend auf der Identität eines Benutzers ändern oder ob ein Benutzer angemeldet ist.

Die VaryByQueryKeys Eigenschaft variiert die gespeicherte Antwort nach den Werten der angegebenen Liste von Abfrageschlüsseln. Wenn ein einzelner Wert des Sternchens (*) für die Wildcard bereitgestellt wird, variiert die Middleware die Antworten nach allen Parametern der Anforderungsabfragezeichenfolge.

Middleware zum Zwischenspeichern von Antworten muss aktiviert sein, damit die Eigenschaft VaryByQueryKeys festgelegt werden kann. Andernfalls wird eine Laufzeitausnahme ausgelöst. Es gibt keinen entsprechenden HTTP-Header für die Eigenschaft VaryByQueryKeys. Die Eigenschaft ist ein HTTP-Feature, das von der Middleware zum Zwischenspeichern von Antworten verarbeitet wird. Damit die Middleware eine zwischengespeicherte Antwort bereitstellen kann, müssen die Abfragezeichenfolge und der Abfragezeichenfolgenwert mit einer vorherigen Anforderung übereinstimmen. Betrachten Sie beispielsweise die Reihenfolge der Anforderungen und Ergebnisse in der folgenden Tabelle:

Request Zurückgegeben von
http://example.com?key1=value1 Server
http://example.com?key1=value1 Middleware
http://example.com?key1=NewValue Server

Der Server gibt die erste Anforderung zurück, und die Middleware speichert die Anforderung zwischen. Die Middleware gibt die zweite Anforderung zurück, da die Abfragezeichenfolge mit der vorherigen (ersten) Anforderung übereinstimmt. Die dritte Anforderung befindet sich nicht im Middlewarecache, da der Abfragezeichenfolgenwert nicht mit einer vorherigen Anforderung übereinstimmt.

Die klasse ResponseCacheAttribute wird zum Konfigurieren und Erstellen (über die schnittstelle IFilterFactory) einer Microsoft.AspNetCore.Mvc.Internal.ResponseCacheFilter verwendet. Der ResponseCacheFilter aktualisiert die entsprechenden HTTP-Header und Features der Antwort. Der Filter:

  • Er entfernt jegliche vorhandenen Header für Vary, Cache-Control und Pragma.
  • Er schreibt die geeigneten Header basierend auf den im ResponseCacheAttribute festgelegten Eigenschaften.
  • Aktualisiert das HTTP-Feature für den Antwort-Cache, wenn die Eigenschaft VaryByQueryKeys festgelegt ist.

Kopfzeile variieren

Dieser Header wird nur geschrieben, wenn die Eigenschaft VaryByHeader festgelegt ist. Die Eigenschaft wird auf den Wert der Vary Eigenschaft festgelegt. Das folgende Beispiel verwendet die Eigenschaft VaryByHeader:

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

Zeigen Sie die Antwortheader mit Fiddler oder einem anderen Tool an. Die Antwortheader umfassen Folgendes:

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

Der vorangehende Code erfordert das Hinzufügen der Methode Response Caching Middleware services AddResponseCaching zur Dienstesammlung. Der Code konfiguriert die App für die Verwendung der Middleware mit der UseResponseCaching Erweiterungsmethode.

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 und Location.None Eigenschaften

Die NoStore Eigenschaft setzt die meisten anderen Eigenschaften außer Kraft. Wenn diese Eigenschaft auf true festgelegt ist, wird der Cache-Control-Header auf no-store festgelegt. Wenn die Location Eigenschaft auf None gesetzt ist:

  • Der Cache-Control-Header wird auf no-store,no-cache festgelegt.
  • Der Pragma Header ist auf no-cache gesetzt.

Wenn die NoStore Eigenschaft auf false und die Location Eigenschaft auf None festgelegt ist, werden die Kopfzeilen Cache-Control und Pragma auf no-cache festgelegt.

Die NoStore Eigenschaft wird in der Regel auf true für Fehlerseiten festgelegt. Der folgende Code erzeugt Antwortheader, die den Client anweisen, die Antwort nicht zu speichern.

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

Der obige Code enthält die folgenden Header in der Antwort:

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

Um das ResponseCacheAttribute Attribut auf alle MVC-Controller- oder Razor Seitenantworten der App anzuwenden, fügen Sie das Attribut mit einem MVC-Filter oder Razor einem Seitenfilter hinzu.

Fügen Sie in einer MVC-App den folgenden Code hinzu:

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

Ein Ansatz, der für Razor Pages-Apps gilt, finden Sie unter GitHub dotnet/aspnetcore Issue #18890 - . Das Hinzufügen des ResponseCacheAttribute zur globalen Filterliste von MVC gilt nicht für Razor Pages. Das Kommentarbeispiel im Problem gilt für ASP.NET Core Apps, die vor der Veröffentlichung von Minimal-APIs (ASP.NET Core Version 6.0) liegen. Für Apps, die auf Version 6.0 und höher abzielen, ändern Sie die im Beispiel verwendete Dienstregistrierung in der Datei Program.cs auf builder.Services.AddSingleton....

"‘Location’- und ‘Duration’-Eigenschaften"

Zum Aktivieren der Zwischenspeicherung muss die Duration Eigenschaft auf einen positiven Wert festgelegt werden und Location muss entweder Any (Standard) oder Client. Das Framework legt den Cache-Control-Header auf den Wert für den Speicherort gefolgt vom max-age-Wert der Antwort fest.

Die Eigenschaftenoptionen von Location bei Any und Client werden jeweils in Cache-Control-Kopfzeilenwerte von public und private übersetzt. Wie im Abschnitt NoStore und Location.None erwähnt, legt das Setzen der Location-Eigenschaft auf None sowohl die Cache-Control- als auch die Pragma-Header auf no-cache fest.

Die Location.Any (Cache-Control auf public) festgelegte Eigenschaftseinstellung gibt an, dass der Client oder ein beliebiger Zwischenproxy den Wert zwischenspeichern kann, einschließlich Middleware für die Zwischenspeicherung von Antworten.

Die Location.Client (Cache-Control auf private) festgelegte Eigenschaftseinstellung gibt an, dass nur der Client den Wert zwischenspeichern kann. Der Wert darf nicht durch einen zwischengeschalteten Cache – einschließlich einer Middleware zum Zwischenspeichern von Antworten – zwischengespeichert werden.

Cache-Control-Header bieten Anleitungen für Clients und zwischengeschaltete Proxys, wann und wie Antworten zwischengespeichert werden sollen. Es gibt keine Garantie dafür, dass Clients und Proxys die RFC 9111: HTTP Caching-Spezifikation berücksichtigen. Middleware zum Zwischenspeichern von Antworten erfüllt immer die durch die Spezifikation festgelegten Zwischenspeicherungsregeln.

Das folgende Beispiel zeigt die Kopfzeilen, die durch das Festlegen der Duration-Eigenschaft und das Belassen des Standardwerts der Location-Eigenschaft erzeugt werden:

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

Der obige Code enthält die folgenden Header in der Antwort:

Cache-Control: public,max-age=10

Cacheprofile

Anstatt die Einstellungen des Antwortcaches für viele Controlleraktionsattribute zu duplizieren, können Cacheprofile beim Einrichten von MVC-Seiten oder Razor -Seiten als Optionen konfiguriert werden. Werte, die in einem referenzierten Cacheprofil gefunden werden, werden als Vorgabewerte von der ResponseCacheAttribute verwendet. Alle Eigenschaften, die für das Attribut angegeben sind, setzen die referenzierten Cacheprofilwerte außer Kraft.

Das folgende Beispiel zeigt ein 30-Sekunden-Cacheprofil:

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();

Der folgende Code verweist auf das Cacheprofil Default30:

[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());
}

Die resultierende Headerantwort vom Cacheprofil Default30 enthält Folgendes:

Cache-Control: public,max-age=30

Sie können das [ResponseCache]-Attribut auf Razor Seiten, MVC-Controller und MVC-Aktionsmethoden anwenden.

In Razor Seiten können Sie Attribute nicht auf Handlermethoden anwenden, da Browser, die mit UI-Apps verwendet werden, das Zwischenspeichern von Antworten verhindern. In einer MVC-Aktionsmethode überschreiben die Attribute auf Methodenebene die in Attributen auf Klassenebene angegebenen Einstellungen.

Der folgende Code wendet das Attribut [ResponseCache] auf Controller- und Methodenebene an:

[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());
}

Anzeigen oder Herunterladen von Beispielcode (Vorgehensweise zum Herunterladen)

Das Zwischenspeichern von Antworten reduziert die Anzahl von Anforderungen, die ein Client oder Proxy an einen Webserver sendet. Das Zwischenspeichern von Antworten reduziert auch den Aufwand zum Generieren einer Antwort durch den Webserver. Das Zwischenspeichern von Antworten wird durch Header gesteuert, die angeben, wie Client, Proxy und Middleware Antworten zwischenspeichern sollen.

Der [ResponseCache] ist an der Festlegung der Header für das Zwischenspeichern von Antworten beteiligt. Clients und zwischengeschaltete Proxys müssen die Header zum Zwischenspeichern von Antworten gemäß RFC 9111: HTTP Caching berücksichtigen.

Zum serverseitigen Zwischenspeichern entsprechend der Spezifikation „HTTP 1.1 Caching“ verwenden Sie Middleware zum Zwischenspeichern von Antworten. Die Middleware kann die [ResponseCache]-Eigenschaften zum Festlegen der Header für die serverseitige Zwischenspeicherung verwenden.

HTTP-basiertes Zwischenspeichern von Antworten

RFC 9111: HTTP Caching beschreibt, wie sich Internet-Caches verhalten sollten. Der für die Zwischenspeicherung verwendete primäre HTTP-Header ist Cache-Control – damit werden Anweisungen für den Cache angegeben. Die Anweisungen steuern das Verhalten der Zwischenspeicherung, wenn Anforderungen von Clients an Server weitergeleitet werden und die Antworten der Server wieder an die Clients weitergeleitet werden. Anforderungen und Antworten werden über Proxyserver übertragen, und auch die Proxyserver müssen die HTTP 1.1 Caching-Spezifikation erfüllen.

Die folgende Tabelle zeigt gängige Cache-Control-Anweisungen.

Directive Action
public Die Antwort kann in einem Cache gespeichert werden.
private Die Antwort darf nicht in einem freigegebenen Cache gespeichert werden. Ein privater Cache kann die Antwort speichern und wiederverwenden.
max-age Der Client akzeptiert keine Antwort, deren Alter größer ist als die angegebene Anzahl von Sekunden. Beispiele: max-age=60 (60 Sekunden), max-age=2592000 (1 Monat)
no-cache Bei Anforderungen: Ein Cache darf keine gespeicherte Antwort verwenden, um die Anforderung zu erfüllen. Der Ursprungsserver generiert die Antwort für den Client neu, und die Middleware aktualisiert die gespeicherte Antwort in ihrem Cache.

Bei Antworten: Die Antwort darf ohne Validierung auf dem Ursprungsserver nicht für eine nachfolgende Anforderung verwendet werden.
no-store Bei Anforderungen: Die Anforderung darf nicht in einem Cache gespeichert werden.

Bei Antworten: Kein Teil der Antwort darf in einem Cache gespeichert werden.

Die folgende Tabelle führt weitere Cacheheader auf, die beim Zwischenspeichern eine Rolle spielen.

Header Function
Age Eine Schätzung der Zeitspanne in Sekunden, seit die Antwort auf dem Ursprungsserver generiert oder erfolgreich validiert wurde.
Expires Der Zeitpunkt, nach dem die Antwort als veraltet betrachtet wird.
Pragma Existiert aus Gründen der Abwärtskompatibilität mit HTTP/1.0-Caches zum Festlegen des Verhaltens von no-cache. Wenn der Cache-Control-Header vorhanden ist, wird der Pragma-Header ignoriert.
Vary Gibt an, dass eine zwischengespeicherte Antwort nur gesendet werden darf, wenn alle Vary-Headerfelder sowohl in der ursprünglichen als auch in der neuen Anforderung der zwischengespeicherten Antwort übereinstimmen.

HTTP-basierte Zwischenspeicherung berücksichtigt Cache-Control-Anweisungen der Anforderung

RFC 9111: HTTP Caching (Section 5.2. Cache-Control) erfordert, dass ein Cache einen vom Client gesendeten gültigen Cache-Control-Header berücksichtigt. Ein Client kann Anforderungen mit dem Headerwert no-cache senden und den Server zwingen, für jede Anforderung eine neue Antwort zu generieren.

In Anbetracht des Ziels der HTTP-Zwischenspeicherung ist es sinnvoll, Cache-Control-Anforderungsheader immer zu berücksichtigen. Gemäß der offiziellen Spezifikation soll das Zwischenspeichern die Latenz und den Netzwerkoverhead beim Verarbeiten von Anforderungen in einem Netzwerk aus Clients, Proxys und Servern reduzieren. Es ist nicht unbedingt eine Möglichkeit, die Last auf einem Ursprungsserver zu steuern.

Entwickler*innen können dieses Verhalten der Zwischenspeicherung bei Verwendung der Middleware zum Zwischenspeichern von Antworten nicht steuern, da die Middleware die offizielle Spezifikation für die Zwischenspeicherung einhält. Die Unterstützung für die Ausgabezwischenspeicherung zur besseren Steuerung der Serverlast ist ein Designvorschlag für ein zukünftiges Release von ASP.NET Core. Weitere Informationen finden Sie unter Add support for Output Caching (dotnet/aspnetcore #27387) (Hinzufügen von Unterstützung für die Ausgabezwischenspeicherung (dotnet/aspnetcore #27387)).

Andere Zwischenspeicherungstechnologien in ASP.NET Core

In-Memory-Caching

Die In-Memory-Zwischenspeicherung verwendet Serverspeicher zur Speicherung zwischengespeicherter Daten. Diese Art des Zwischenspeicherns eignet sich für einen einzelnen Server oder für mehrere Server mit Sitzungsaffinität. Die Sitzungsaffinität wird auch als Sticky Sessions bezeichnet. Sitzungsaffinität bedeutet, dass die Anforderungen von einem Client immer an denselben Server zur Verarbeitung weitergeleitet werden.

Weitere Informationen finden Sie unter In-Memory-Zwischenspeicherung in ASP.NET Core und unter Behandeln von Problemen mit der Azure Application Gateway-Sitzungsaffinität.

Verteilter Cache

Verwenden Sie einen verteilten Cache, um Daten im Arbeitsspeicher zu speichern, wenn die App in einer Cloud oder Serverfarm gehostet wird. Der Cache wird von den Servern, die Anforderungen verarbeiten, gemeinsam genutzt. Ein Client kann eine Anforderung übermitteln, die von einem beliebigen Server in der Gruppe verarbeitet wird, wenn zwischengespeicherte Daten für den Client verfügbar sind. ASP.NET Core unterstützt verteilte Caches mit SQL Server, Redis, Postgres und NCache.

Weitere Informationen finden Sie unter Verteiltes Zwischenspeichern in ASP.NET Core.

Cache-Tag-Hilfsprogramm

Speichern Sie den Inhalt aus einer MVC-Ansicht oder einer Razor Page-Instanz mit dem Cache-Taghilfsprogramm zwischen. Das Cache-Taghilfsprogramm verwendet die In-Memory-Zwischenspeicherung zum Speichern von Daten.

Weitere Informationen finden Sie unter Cache-Taghilfsprogramm im ASP.NET Core MVC.

Cache-Tag-Hilfsprogramm für verteilte Systeme

Speichern Sie den Inhalt aus einer MVC-Ansicht oder einer Razor Seite in verteilten Cloud- oder Webfarmszenarien mithilfe des Distributed Cache Tag Helpers. Das Taghilfsprogramm für verteilten Cache verwendet SQL Server, Redis oder NCache zum Speichern von Daten.

Weitere Informationen finden Sie unter Taghilfsprogramm für verteilten Cache in ASP.NET Core.

ResponseCache-Attribut

DasResponseCacheAttribute gibt die Parameter an, die beim Zwischenspeichern von Antworten zum Festlegen geeigneter Header erforderlich sind.

Warning

Deaktivieren Sie die Zwischenspeicherung für Inhalte, die Informationen für authentifizierte Clients enthalten. Das Zwischenspeichern sollte nur für Inhalte aktiviert werden, die sich nicht basierend auf der Identität eines Benutzers ändern oder ob ein Benutzer angemeldet ist.

VaryByQueryKeys variiert die gespeicherte Antwort anhand der Werte in der angegebenen Liste mit Abfrageschlüsseln. Wenn der einzelne Wert * angegeben ist, variiert die Middleware Antworten anhand sämtlicher Parameter der Abfragezeichenfolge der Anforderung.

Middleware zum Zwischenspeichern von Antworten muss aktiviert sein, damit die Eigenschaft VaryByQueryKeys festgelegt werden kann. Andernfalls wird eine Laufzeitausnahme ausgelöst. Es gibt keinen entsprechenden HTTP-Header für die Eigenschaft VaryByQueryKeys. Die Eigenschaft ist ein HTTP-Feature, das von der Middleware zum Zwischenspeichern von Antworten verarbeitet wird. Damit die Middleware eine zwischengespeicherte Antwort bereitstellen kann, müssen die Abfragezeichenfolge und der Abfragezeichenfolgenwert mit einer vorherigen Anforderung übereinstimmen. Betrachten Sie beispielsweise die Reihenfolge der Anforderungen und Ergebnisse in der folgenden Tabelle.

Request Result
http://example.com?key1=value1 Vom Server zurückgegeben.
http://example.com?key1=value1 Von Middleware zurückgegeben.
http://example.com?key1=value2 Vom Server zurückgegeben.

Die erste Anforderung wird vom Server zurückgegeben und in der Middleware zwischengespeichert. Die zweite Anforderung wird von der Middleware zurückgegeben, da die Abfragezeichenfolge mit der vorherigen Anforderung übereinstimmt. Die dritte Anforderung befindet sich nicht im Middlewarecache, da der Abfragezeichenfolgenwert nicht mit einer vorherigen Anforderung übereinstimmt.

Das ResponseCacheAttribute wird zum Konfigurieren und Erstellen (über IFilterFactory) eines Microsoft.AspNetCore.Mvc.Internal.ResponseCacheFilter verwendet. Der ResponseCacheFilter aktualisiert die entsprechenden HTTP-Header und Features der Antwort. Der Filter:

  • Er entfernt jegliche vorhandenen Header für Vary, Cache-Control und Pragma.
  • Er schreibt die geeigneten Header basierend auf den im ResponseCacheAttribute festgelegten Eigenschaften.
  • Aktualisiert das HTTP-Feature für Antwort-Cache, wenn VaryByQueryKeys festgelegt ist.

Vary

Dieser Header wird nur geschrieben, wenn die Eigenschaft VaryByHeader festgelegt ist. Die Eigenschaft wird auf den Wert der Eigenschaft Vary festgelegt. Das folgende Beispiel verwendet die Eigenschaft VaryByHeader:

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

Verwenden Sie die Beispiel-App, um die Antwortheader mit den Netzwerktools des Browsers anzuzeigen. Die folgenden Antwortheader werden mit der Cache1-Seitenantwort gesendet:

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

NoStore und Location.None

NoStore überschreibt die meisten der anderen Eigenschaften. Wenn diese Eigenschaft auf true festgelegt ist, wird der Cache-Control-Header auf no-store festgelegt. Wenn Location auf None festgelegt ist:

  • Cache-Control ist auf no-store,no-cache festgelegt.
  • Pragma ist auf no-cache gesetzt.

Wenn NoStore als false und Location als None festgelegt ist, werden Cache-Control und Pragma auf no-cache festgelegt.

NoStore ist für Fehlerseiten in der Regel auf true festgelegt. Die Cache2-Seite in der Beispiel-App erzeugt Antwortheader, die den Client anweisen, die Antwort nicht zu speichern.

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

Die Beispiel-App gibt die Cache2-Seite mit den folgenden Headern zurück:

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

Um den ResponseCacheAttribute auf alle MVC-Controller oder Razor Seitenantworten der App anzuwenden, fügen Sie ihn mit einem MVC-Filter oder RazorSeitenfilter hinzu.

In einer MVC-App:

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

Informationen zu einer Vorgehensweise für Razor Pages-Apps finden Sie unter Adding ResponseCacheAttribute to MVC global filter list does not apply to Razor Pages (dotnet/aspnetcore #18890) (Hinzufügen von ResponseCacheAttribute zur globalen MVC-Filterliste gilt nicht für Razor Pages (dotnet/aspnetcore #18890)).

Ort und Dauer

Zum Aktivieren der Zwischenspeicherung muss Duration auf einen positiven Wert festgelegt sein, und Location muss entweder Any (Standardwert) oder Client lauten. Das Framework legt den Cache-Control-Header auf den Wert für den Speicherort gefolgt vom max-age-Wert der Antwort fest.

Die Location-Optionen für Any und Client werden in die Cache-Control-Headerwerte public bzw. private übersetzt. Wie im Abschnitt „NoStore“ und „Location.None“ erläutert: Wenn Location auf None festgelegt ist, wird sowohl der Cache-Control-Header als auch der Pragma-Header auf no-cache festgelegt.

Location.Any (Cache-Control auf public festgelegt) gibt an, dass der Client oder ein beliebiger zwischengeschalteter Proxy den Wert zwischenspeichern darf, einschließlich einer Middleware zum Zwischenspeichern von Antworten.

Location.Client (Cache-Control auf private festgelegt) gibt an, dass nur der Client den Wert zwischenspeichern darf. Der Wert darf nicht durch einen zwischengeschalteten Cache – einschließlich einer Middleware zum Zwischenspeichern von Antworten – zwischengespeichert werden.

Cache-Control-Header bieten Clients und zwischengeschalteten Proxys nur Hinweise, wann und wie Antworten zwischengespeichert werden. Es gibt keine Garantie, dass Clients und Proxys RFC 9111: HTTP Caching erfüllen. Middleware zum Zwischenspeichern von Antworten erfüllt immer die durch die Spezifikation festgelegten Zwischenspeicherungsregeln.

Das folgende Beispiel zeigt das Cache3-Seitenmodell der Beispiel-App und die Header, die erzeugt werden, indem Duration festgelegt und der Standardwert für Location beibehalten wird:

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

Die Beispiel-App gibt die Cache3-Seite mit dem folgenden Header zurück:

Cache-Control: public,max-age=10

Cacheprofile

Anstatt die Antwortcache-Einstellungen in vielen Controlleraktionsattributen zu duplizieren, können Cacheprofile bei der Einrichtung von MVC/Razor Pages in Startup.ConfigureServices als Optionen konfiguriert werden. Die Werte, die sich in einem referenzierten Cacheprofil befinden, werden vom ResponseCacheAttribute als Standardwerte verwendet und von jeglichen im Attribut angegebenen Eigenschaften überschrieben.

Richten Sie ein Cacheprofil ein. Das folgende Beispiel zeigt ein Cacheprofil mit 30 Sekunden im Startup.ConfigureServices-Element der Beispiel-App:

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

Das Cache4-Seitenmodell der Beispiel-App verweist auf das Cacheprofil Default30:

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

Das ResponseCacheAttribute kann auf Folgendes angewendet werden:

  • Razor Pages: Attribute können nicht auf Handlermethoden angewendet werden.
  • MVC-Controller.
  • MVC-Aktionsmethoden: Attribute auf Methodenebene überschreiben die Einstellungen, die in Attributen auf Klassenebene angegeben sind.

Der resultierende Header, der vom Cacheprofil Default30 auf die Cache4-Seitenantwort angewendet wird:

Cache-Control: public,max-age=30

Weitere Ressourcen