Where is output cache in ASP.NET Core? Is it gone? No, it’s there but in new and better extensible form and it is called now response caching. This blog post shows how to use response caching on ASP.NET Core and provides tips about some internals of it.
In ASP.NET Core caching is solved as middleware service that comes with Microsoft.AspNetCore.ResponseCaching NuGet package. In MVC caching is driven by ResponseCache attribute. It’s possible to use ResponseCache attribute also without response caching middleware to just set response headers. This way it is possible to tell browser to cache content and also cache or proxy servers on the way can read these headers to find out how to cache page.
By default response caching uses memory based cache but there are extension points that allow to use custom cache storage providers. This blog post doesn’t cover extensibility. It covers just basics and focuses on stateless public sites.
Using respone caching
After adding package reference to Microsoft.AspNetCore.ResponseCaching we can register response caching middleware in Startup class using AddResponseCaching() and UseResponseCaching() extension methods.
public void ConfigureServices(IServiceCollection services)
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
For MVC controller action we add ResponseCache attribute. The following example shows primitive controller action that returns just a simple view it has.
[ResponseCache(Duration = 30)]
public IActionResult Article()
This is enough to get caching work with minimal effort. When we run our application and request controller action that is cached we get the following result:
NB! For full list of cache settings available check out the following pages from official documentation:
- Response Caching (ASP.NET Core documentation)
- Response Caching Middleware (ASP.NET Core documentation)
Caching profiles can be defined in application Startup class and they are supported by ResponseCache attribute.
Conditions for caching
Response caching middleware page by Microsoft lists conditions that request must meet for caching:
- The request must result in a 200 (OK) response from the server.
- The request method must be GET or HEAD.
- Terminal middleware, such as Static File Middleware, must not process the response prior to the Response Caching Middleware.
- The Authorization header must not be present.
- Cache-Control header parameters must be valid, and the response must be marked public and not marked private.
- The Pragma: no-cache header/value must not be present if the Cache-Control header is not 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 HttpSendFileFeature is not used.
- The response must not be stale as specified by the Expires header and the max-age and s-maxage cache directives.
- Response buffering is successful, and the total length of the response is smaller than the configured limit.
- The response must be cacheable according to the RFC 7234 specifications. For example, the no-store directive must not exist in request or response header fields. See Section 3: Storing Responses in Caches of the RFC document for details.
Problems with cookies
For Application Insights and services like this it is technically possible to create custom middleware based on default one if cookies are still needed for client-side libraries and there are no dependencies with application or session state.
To some point it is possible to monitor response caching. The library uses ASP.NET Core logging framework to log some activities by response caching middleware. Screen fragment below shows some response caching middleware logs.
Sadly it does not report reasons why response was not added to cache. It would greatly help us when testing our response caching in different environments.
If logs are not enough then we can always include projects from response caching GitHub repository to our solution and run these on debugger to see what’s going on.
NB! When debugging response caching with browser make sure that developers tools that come with browser doesn’t set any cookies or cache headers that may affect response caching.
Getting rid of ARR affiinity cookie on Azure Web Sites
If your site doesn’t need Application Request Routing (ARR) you can disable ARR affinity cookie by adding the following block of settings to web.config of your web application.
<add name="ARR-Disable-Session-Affinity" value="true"/>
After this modification there is no more ARR cookie in your site available anymore.