Caching keeps a previously generated value or response so a later request can reuse it. In ASP.NET Core, the choice is what to retain: a data value an endpoint can read, an entire response that can bypass the endpoint, or a fragment of a Razor view. Use it when regeneration is costly, not simply because a cache is available. section 17.0 section 17.6 section 26.6
Choose the cache at the point where repeated work occurs:
- For a data value, register an IDistributedCache implementation and inject it into the endpoint. Read with GetStringAsync(key); on a miss, calculate and store with SetStringAsync(key, value, options). DistributedCacheEntryOptions can set an absolute expiry, a relative expiry, or an inactivity-based sliding expiry. AddDistributedMemoryCache stores values only in the current runtime instance despite its name; SQL Server and Redis implementations are alternatives. section 17.2.1 section 16.3.1
- For HTTP response caching, register AddResponseCaching and place UseResponseCaching before the endpoint or middleware whose response needs caching. The response must set a Cache-Control header with public; max-age specifies its lifetime in seconds. This cache is in memory, does not use IDistributedCache, and does not serve every request from cache. section 17.3
- For output caching, register AddOutputCache, add UseOutputCache, and opt an endpoint in with CacheOutput(). The middleware can satisfy a request without running the endpoint, so the endpoint need not set a caching header. The default policy lasts one minute and caches eligible GET or HEAD requests that return HTTP 200. Define a base or named policy to change its duration; a controller action can select one with OutputCache(PolicyName = "30sec"). section 17.4 section 17.4.1 section 20.4.6
- For a Razor fragment, wrap the markup in a cache element. Use expires-after, expires-on, or expires-sliding to control expiry, and a vary-by attribute when different requests need different versions. The memory-based cache is separate on each application server and is lost on restart; distributed-cache uses a shared cache. section 26.6 section 26.6.1
Check a cached calculation
At /sum/{count}, use a key such as sum_ plus the route count. On a miss, calculate the sum, include the current time in the stored string, and set AbsoluteExpirationRelativeToNow to two minutes. The in-memory example registers AddDistributedMemoryCache with SizeLimit = 200. Request /sum, then reload: the response’s current timestamp changes, but the timestamp stored with the calculation does not. After two minutes, both change. Size the memory cache with server resources in mind. section 17.2.1
Check an entire cached response
An endpoint can instead return HTML with Cache-Control: public, max-age=120. To check response caching, follow a link to its URL rather than reloading: browser reloads can send a request header with max-age=0 that bypasses the response cache. With output caching, repeated requests to the same URL can reuse the output without this endpoint-managed header. section 17.3 section 17.4
Listing 17.19 A custom configuration in the Program.cs file in the Platform folder
using Platform.Services;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddOutputCache(opts => {
opts.AddBasePolicy(policy => {
policy.Cache();
policy.Expire(TimeSpan.FromSeconds(10));
});
opts.AddPolicy("30sec", policy => {
policy.Cache();
policy.Expire(TimeSpan.FromSeconds(30));
});
});
builder.Services.AddSingleton<IResponseFormatter,
HtmlResponseFormatter>();
var app = builder.Build();
app.UseOutputCache();
app.MapEndpoint<Platform
.SumEndpoint>("/sum/{count:int=1000000000}")
.CacheOutput();
app.MapEndpoint<Platform
.SumEndpoint>("/sum30/{count:int=1000000000}")
.CacheOutput("30sec");
app.MapGet("/", async context => {
await context.Response.WriteAsync("Hello World!");
});
app.Run();
Program.cs example defining a 10-second base output-cache policy and a named 30-second policy, then applying each to a different sum route. section 17.4.1
A cache can also back session data, but an in-memory session cache disappears when the application stops and is not shared across runtime instances. More generally, stale content, inconsistent copies on different servers, and content left over from a previous deployment can outweigh a performance gain. Test the policy against a defined performance problem before deploying it. Output caching is not interchangeable with IDistributedCache: persistent output-cache storage has an API but no default implementation, and output caching requires careful locking. section 16.3.2 section 26.6 section 17.4





































