Zwischenspeichern von Antworten in ASP.NET Core

Von Rick Anderson und Kirk Larkin

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 in Headern festgelegt.

Das ResponseCache-Attribut legt die Header für das Zwischenspeichern von Antworten fest. 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 ResponseCacheAttribute-Eigenschaften verwenden, um das Verhalten beim serverseitigen Zwischenspeichern zu beeinflussen.

Für die Middleware zum Zwischenspeichern von Antworten gilt Folgendes:

  • Ermöglicht das Zwischenspeichern von Serverantworten basierend auf HTTP-Cacheheadern. Implementiert die standardmäßige HTTP-Zwischenspeicherungssemantik. Führt die Zwischenspeicherung basierend auf HTTP-Cacheheadern durch – genauso wie Proxys.
  • Ist in der Regel nicht vorteilhaft für Benutzeroberflächen-Apps wie Razor Pages, da Browser im Allgemeinen Anforderungsheader festlegen, die das Zwischenspeichern verhindern. Benutzeroberflächen-Apps profitieren von der Ausgabezwischenspeicherung, die in ASP.NET Core 7.0 und höher verfügbar ist. Bei der Ausgabezwischenspeicherung entscheidet die Konfiguration unabhängig von HTTP-Headern, was zwischengespeichert werden soll.
  • Dies kann bei öffentlichen GET- oder HEAD API-Anforderungen von Clients von Vorteil sein, wenn die Bedingungen für die Zwischenspeicherung erfüllt sind.

Verwenden Sie zum Testen der Antwortzwischenspeicherung 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.

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.

Anweisung Aktion
öffentlich 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 Wert für das Alter größer als die angegebene Anzahl von Sekunden ist. 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 Funktion
Alter Eine Schätzung der Zeitspanne in Sekunden, seit die Antwort auf dem Ursprungsserver generiert oder erfolgreich validiert wurde.
Läuft ab 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. In .NET 7 wurde Unterstützung für die Ausgabezwischenspeicherung hinzugefügt, damit die Serverlast besser gesteuert werden kann. Weitere Informationen finden Sie unter Ausgabezwischenspeicherung.

ResponseCache-Attribut

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

Warnung

Deaktivieren Sie die Zwischenspeicherung für Inhalte, die Informationen für authentifizierte Clients enthalten. Die Zwischenspeicherung sollte nur für Inhalte aktiviert werden, die sich nicht ändern, je nachdem, welche Identität Benutzer*innen haben oder ob Benutzer*innen angemeldet sind.

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:

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

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 führt folgende Aktionen aus:

  • Er entfernt jegliche vorhandenen Header für Vary, Cache-Control und Pragma.
  • Er schreibt die geeigneten Header basierend auf den im ResponseCacheAttribute festgelegten Eigenschaften.
  • Er aktualisiert das HTTP-Feature für die Antwortzwischenspeicherung, 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:

[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 oben stehende Code erfordert das Hinzufügen der Methode AddResponseCaching der Middleware zum Zwischenspeichern von Antworten zur Dienstsammlung und konfiguriert die App für die Verwendung der Middleware mit der Erweiterungsmethode UseResponseCaching.

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

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:

  • Für Cache-Control ist no-store,no-cache festgelegt.
  • Für Pragma ist no-cache festgelegt.

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. 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 auf alle Antworten von MVC-Controllern oder Razor Pages-Seiten einer App anzuwenden, fügen Sie es mit einem MVC-Filter oder einem Razor Pages-Filter hinzu.

In einer MVC-App:

builder.Services.AddControllersWithViews().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)). Das im Kommentar zu diesem Issue bereitgestellte Beispiel wurde für Apps geschrieben, die für ASP.NET Core vor der Veröffentlichung von Minimal-APIs in 6.0 konzipiert sind. Bei Apps für 6.0 oder höher ändern Sie die Dienstregistrierung im Beispiel für Program.cs zu builder.Services.AddSingleton....

Speicherort 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 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 die Header, die erzeugt werden, indem Duration festgelegt und der Standardwert für Location beibehalten wird:

[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 Antwortcacheeinstellungen in vielen Controlleraktionsattribute zu duplizieren, können beim Einrichten von MVC/Razor Pages Cacheprofile 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.

Das folgende Beispiel zeigt ein Cacheprofil mit 30 Sekunden:

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

Das [ResponseCache]-Attribut kann auf Folgendes angewendet werden:

  • Razor Pages: Attribute können nicht auf Handlermethoden angewendet werden. Browser, die mit Benutzeroberflächen-Apps verwendet werden, verhindern das Zwischenspeichern von Antworten.
  • MVC-Controller.
  • MVC-Aktionsmethoden: Attribute auf Methodenebene überschreiben die Einstellungen, die in Attributen auf Klassenebene angegeben sind.

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

Zusätzliche Ressourcen

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.

Anweisung Aktion
öffentlich 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 Wert für das Alter größer als die angegebene Anzahl von Sekunden ist. 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 Funktion
Alter Eine Schätzung der Zeitspanne in Sekunden, seit die Antwort auf dem Ursprungsserver generiert oder erfolgreich validiert wurde.
Läuft ab 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 Serverarbeitsspeicher zur Aufbewahrung 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 funktioniert mit verteilten Caches von SQL Server, Redis und NCache.

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

Cache-Taghilfsprogramm

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.

Taghilfsprogramm für verteilten Cache

Speichern Sie den Inhalt aus einer MVC-Ansicht oder einer Razor Page-Instanz in verteilten Cloud- oder Webfarmszenarien mit dem Taghilfsprogramm für verteilten Cache zwischen. 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.

Warnung

Deaktivieren Sie die Zwischenspeicherung für Inhalte, die Informationen für authentifizierte Clients enthalten. Die Zwischenspeicherung sollte nur für Inhalte aktiviert werden, die sich nicht ändern, je nachdem, welche Identität Benutzer*innen haben oder ob Benutzer*innen angemeldet sind.

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.

Anfordern Ergebnis
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 führt folgende Aktionen aus:

  • Er entfernt jegliche vorhandenen Header für Vary, Cache-Control und Pragma.
  • Er schreibt die geeigneten Header basierend auf den im ResponseCacheAttribute festgelegten Eigenschaften.
  • Er aktualisiert das HTTP-Feature für die Antwortzwischenspeicherung, 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:

  • Für Cache-Control ist no-store,no-cache festgelegt.
  • Für Pragma ist no-cache festgelegt.

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 das ResponseCacheAttribute auf alle Antworten von MVC-Controllern oder Razor Pages-Seiten einer App anzuwenden, fügen Sie es mit einem MVC-Filter oder einem Razor Pages-Filter 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)).

Speicherort 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 Antwortcacheeinstellungen in vielen Controlleraktionsattribute zu duplizieren, können beim Einrichten von MVC/Razor Pages in Startup.ConfigureServices Cacheprofile 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

Zusätzliche Ressourcen