Problem
How to cache responses in ASP.NET Core.
Solution
To an empty project, configure services and middleware for caching in Startup
:
public void ConfigureServices(
IServiceCollection services)
{
services.AddResponseCaching();
services.AddMvc();
}
public void Configure(
IApplicationBuilder app,
IHostingEnvironment env)
{
app.UseResponseCaching();
app.UseMvcWithDefaultRoute();
}
Create a controller, annotate with [ResponseCache]
attribute:
[ResponseCache(Duration = 60)]
public class HomeController : Controller
{
public IActionResult Index()
{
return View(new HomeOutputModel
{
LastUpdated = DateTime.Now
});
}
}
The response will contain a Cache-Control
header:
As you navigate between a controller with caching enabled (Home
) and another one without it (Movies
), you’ll notice that time isn’t being updated, i.e., not coming from server but rather from cache:
Discussion
Response Caching middleware is responsible for storing and serving responses from a cache. It adds cache related headers to HTTP responses, primary one being Cache-Control
.
Once middleware is setup, [ResponseCache]
attribute is applied on controller/action to enable caching. The attribute has some useful parameters to alter the behaviour of middleware:
Duration
: Used to set cache expiry (in seconds)
Location
: Translates into Cache-Control
header of public
, private
or no-cache
VaryByQueryKeys
: Responses are cached based on query string parameters
VaryByHeader
: Used to set Vary HTTP response header
CacheProfileName
: Can point to cache profile setup in MVC middleware (see below)
services.AddMvc(options =>
{
options.CacheProfiles.Add("default", new CacheProfile
{
Duration = 30,
Location = ResponseCacheLocation.Any
});
});
Logging
You could enable logging to view the workings of the Response Caching middleware. Below is the first request to Home/Index (see highlighted lines), subsequent requests will go through this lifecycle, and serve the page from cache (until its expiry):