The ASP.NET Core [ResponseCache] attribute sets HTTP response-caching directives on a controller action or Minimal API method. Those directives tell clients and intermediate caches whether they may reuse a response. This helps an API label responses as cacheable or non-cacheable, a REST cacheability requirement. The attribute sets headers; by itself, it does not store responses on the API server. section 3.1.3 section 8.2 section 8.2.4
Choose the settings to match the response:
- Duration sets Cache-Control max-age in seconds. For a board-game GET response, 60 permits reuse for 60 seconds. section 3.1.3
- Location controls who may cache it: Any allows clients and proxies, Private allows clients only, and None sets a no-cache directive. section 3.1.3
- NoStore = true sets no-store. Use it for request-specific error responses that would make no sense to retain. section 3.1.3
// ... [HttpGet(Name = "GetBoardGames")] [ResponseCache(Location = ResponseCacheLocation.Any, Duration = 60)] public IEnumerable<BoardGame> Get() // ...
The board-game GET action allows clients and intermediate caches to reuse its response for 60 seconds. section 3.1.3
For a Minimal API error endpoint, place [ResponseCache(NoStore = true)] on the handler instead. Import Microsoft.AspNetCore.Mvc in Program.cs or the controller file where the attribute is used. Without the attribute, an endpoint may send no Cache-Control header at all; check the response rather than assuming a default. section 3.1.3 section 8.2.2
To verify a directive, run the API, open the browser developer tools’ Network tab, request the endpoint, and inspect its response headers. A board-game GET configured with Location = Any and Duration = 60 should return cache-control: public,max-age=60. Cache-Control can also be written through HttpContext.Response.Headers, but that becomes verbose when directives are repeated. section 8.2.3 section 8.2.1
Repeated settings can be centralized as cache profiles in AddControllers options. For example, define an Any-60 profile for public, 60-second caching and a NoCache profile with NoStore = true. Controller actions can then select a profile by name rather than repeat its settings. section 8.2.3
Listing 8.4 Program.cs file: Cache profiles
builder.Services.AddControllers(options => {
// ... non-relevant code omitted ...
options.CacheProfiles.Add("NoCache", #1
new CacheProfile() { NoStore = true });
options.CacheProfiles.Add("Any-60", #2
new CacheProfile()
{
Location = ResponseCacheLocation.Any,
Duration = 60
});
});
These AddControllers options define the two named profiles; a controller action can use [ResponseCache(CacheProfileName = "Any-60")]. section 8.2.3
A no-cache fallback can cover endpoints that have no attribute: custom middleware sets a default header, while an explicit ResponseCache setting overrides it. If server-side response storage is also needed, add ASP.NET Core response-caching middleware. It follows the response headers, but caches only eligible GET or HEAD responses with a 200 OK status. Consider its server overhead before enabling it. section 8.2.2 section 8.2.4
