Fundamentals - Middleware - Response caching middleware
In this article
-
Enables caching server responses based on HTTP cache headers. Implements the standard HTTP caching semantics. Caches based on HTTP cache headers like proxies do.
-
Is typically not beneficial for UI apps such as Razor Pages because browsers generally set request headers that prevent caching. Output caching, which is available in ASP.NET Core 7.0 and later, benefits UI apps. With output caching, configuration decides what should be cached independently of HTTP headers.
-
May be beneficial for public GET or HEAD API requests from clients where the Conditions for caching are met.
Configuration
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddResponseCaching();
var app = builder.Build();
app.UseHttpsRedirection();
// UseCors must be called before UseResponseCaching
//app.UseCors();
app.UseResponseCaching();
Warning UseCors must be called before
UseResponseCaching
when using CORS middleware.
-
Cache-Control
: Caches cacheable responses for up to 10 seconds. -
Vary
: Configures the middleware to serve a cached response only if the Accept-Encoding header of subsequent requests matches that of the original request.
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddResponseCaching();
var app = builder.Build();
app.UseHttpsRedirection();
// UseCors must be called before UseResponseCaching
//app.UseCors();
app.UseResponseCaching();
app.Use(async (context, next) =>
{
context.Response.GetTypedHeaders().CacheControl =
new Microsoft.Net.Http.Headers.CacheControlHeaderValue()
{
Public = true,
MaxAge = TimeSpan.FromSeconds(10)
};
context.Response.Headers[Microsoft.Net.Http.Headers.HeaderNames.Vary] =
new string[] { "Accept-Encoding" };
await next();
});
app.MapGet("/", () => DateTime.Now.Millisecond);
app.Run();
- Has a
[ResponseCache]
attribute. This applies even if a property isn't set. For example, omitting the VaryByHeader property will cause the corresponding header to be removed from the response.
Warning Responses containing content for authenticated clients must be marked as not cacheable to prevent the middleware from storing and serving those responses. See Conditions for caching for details on how the middleware determines if a response is cacheable.
Options
Option | Description |
---|---|
MaximumBodySize | The largest cacheable size for the response body in bytes. The default value is 64 * 1024 * 1024 (64 MB). |
SizeLimit | The size limit for the response cache middleware in bytes. The default value is 100 * 1024 * 1024 (100 MB). |
UseCaseSensitivePaths | Determines if responses are cached on case-sensitive paths. The default value is false . |
-
Cache responses with a body size smaller than or equal to 1,024 bytes.
-
Store the responses by case-sensitive paths. For example,
/page1
and/Page1
are stored separately.
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddResponseCaching(options =>
{
options.MaximumBodySize = 1024;
options.UseCaseSensitivePaths = true;
});
var app = builder.Build();
app.UseHttpsRedirection();
// UseCors must be called before UseResponseCaching
//app.UseCors();
app.UseResponseCaching();
app.Use(async (context, next) =>
{
context.Response.GetTypedHeaders().CacheControl =
new Microsoft.Net.Http.Headers.CacheControlHeaderValue()
{
Public = true,
MaxAge = TimeSpan.FromSeconds(10)
};
context.Response.Headers[Microsoft.Net.Http.Headers.HeaderNames.Vary] =
new string[] { "Accept-Encoding" };
await next(context);
});
app.MapGet("/", () => DateTime.Now.Millisecond);
app.Run();
VaryByQueryKeys
var responseCachingFeature = context.HttpContext.Features.Get<IResponseCachingFeature>();
if (responseCachingFeature != null)
{
responseCachingFeature.VaryByQueryKeys = new[] { "MyKey" };
}
HTTP headers used by Response Caching Middleware
Header | Details |
---|---|
Authorization |
The response isn't cached if the header exists. |
Cache-Control |
The middleware only considers caching responses marked with the public cache directive. Control caching with the following parameters:
max-stale , the middleware takes no action.‡ proxy-revalidate has the same effect as must-revalidate .For more information, see RFC 9111: Request Directives. |
Pragma |
A Pragma: ```no-cache``` header in the request produces the same effect as Cache-Control: ```no-cache``` . This header is overridden by the relevant directives in the Cache-Control header, if present. Considered for backward compatibility with HTTP/1.0. |
Set-Cookie |
The response isn't cached if the header exists. Any middleware in the request processing pipeline that sets one or more cookies prevents the Response Caching Middleware from caching the response (for example, the cookie-based TempData provider). |
Vary |
The Vary header is used to vary the cached response by another header. For example, cache responses by encoding by including the Vary: Accept-Encoding header, which caches responses for requests with headers Accept-Encoding: gzip and Accept-Encoding: text/plain separately. A response with a header value of * is never stored. |
Expires |
A response deemed stale by this header isn't stored or retrieved unless overridden by other Cache-Control headers. |
If-None-Match |
The full response is served from cache if the value isn't * and the ETag of the response doesn't match any of the values provided. Otherwise, a 304 (Not Modified) response is served. |
If-Modified-Since |
If the If-None-Match header isn't present, a full response is served from cache if the cached response date is newer than the value provided. Otherwise, a 304 - Not Modified response is served. |
Date |
When serving from cache, the Date header is set by the middleware if it wasn't provided on the original response. |
Content-Length |
When serving from cache, the Content-Length header is set by the middleware if it wasn't provided on the original response. |
Age |
The Age header sent in the original response is ignored. The middleware computes a new value when serving a cached response. |
- ```max-age```
- ```max-stale```†
- min-fresh
- ```must-revalidate```
- ```no-cache```
- ```no-store```
- only-if-cached
- ```private```
- public
- ```s-maxage```
- ```proxy-revalidate```‡
Cache-Control
directives
Caching respects request -
Cache in-memory in ASP.NET Core
-
Distributed caching in ASP.NET Core
-
Cache Tag Helper in ASP.NET Core MVC
-
Distributed Cache Tag Helper in ASP.NET Core
Troubleshooting
Conditions for caching
-
The request must result in a server response with a 200 (OK) status code.
-
The request method must be GET or HEAD.
-
Response Caching Middleware must be placed before middleware that require caching. For more information, see ASP.NET Core Middleware.
-
The
Authorization
header must not be present. -
Cache-Control
header parameters must be valid, and the response must be marked public and not markedprivate
. -
The
Pragma:
no-cache`````` header must not be present if theCache-Control
header isn't present, as the ```Cache-Control``` header overrides the ```Pragma``` header when present. -
The
Set-Cookie
header must not be present. -
Vary
header parameters must be valid and not equal to *. -
The
Content-Length
header value (if set) must match the size of the response body. -
The IHttpSendFileFeature isn't used.
-
The response must not be stale as specified by the
Expires
header and themax-age
ands-maxage
cache directives. -
Response buffering must be successful. The size of the response must be smaller than the configured or default SizeLimit. The body size of the response must be smaller than the configured or default MaximumBodySize.
-
The response must be cacheable according to RFC 9111: HTTP Caching. For example, the
no-store
directive must not exist in request or response header fields. See RFC 9111: HTTP Caching (Section 3: Storing Responses in Caches for details.
Note The Antiforgery system for generating secure tokens to prevent Cross-Site Request Forgery (CSRF) attacks sets the
Cache-Control
andPragma
headers tono-cache
so that responses aren't cached. For information on how to disable antiforgery tokens for HTML form elements, see Prevent Cross-Site Request Forgery (XSRF/CSRF) attacks in ASP.NET Core.
Additional resources
-
View or download sample code (how to download)
-
GitHub source for
IResponseCachingPolicyProvider
-
GitHub source for
IResponseCachingPolicyProvider
-
App startup in ASP.NET Core
-
ASP.NET Core Middleware
-
Cache in-memory in ASP.NET Core
-
Distributed caching in ASP.NET Core
-
Detect changes with change tokens in ASP.NET Core
-
Response caching in ASP.NET Core
-
Cache Tag Helper in ASP.NET Core MVC
-
Distributed Cache Tag Helper in ASP.NET Core