ASP.NET Core 7起内置Output Caching替代[ResponseCache]和IMemoryCache,基于中间件实现、支持策略化与共享缓存,适用于所有HTTP终结点;需在Program.cs中调用AddOutputCaching()和UseOutputCaching(),并可通过[OutputCache]特性或WithMetadata配置缓存策略,支持Duration、VaryByQueryKeys、VaryByHeader等参数,自动设置Cache-Control头,命中时返回X-Output-Cache: Hit。

ASP.NET Core 7 开始内置了 Output Caching(输出缓存),替代了旧版的 [ResponseCache] 和 IMemoryCache 手动缓存响应体的方式,支持更细粒度、可策略化、可共享的 HTTP 级别响应缓存。它基于中间件实现,不依赖控制器或视图,适用于 MVC、Razor Pages、Minimal API 等所有 HTTP 终结点。
启用 Output Caching 中间件
在 Program.cs 中注册并启用缓存服务和中间件:
- 调用
builder.Services.AddOutputCaching()添加服务(支持自定义缓存提供者,如内存、分布式) - 在
app.UseOutputCaching()添加中间件,必须放在UseRouting之后、UseEndpoints或Map之前
示例:
var builder = WebApplication.CreateBuilder(args); builder.Services.AddOutputCaching(); // 默认使用内存缓存 var app = builder.Build(); app.UseRouting(); app.UseOutputCaching(); // ⚠️ 位置很重要 app.MapControllers(); app.Run();
为 Minimal API 或控制器配置缓存策略
有两种主流方式:声明式(特性)和代码式(委托)。推荐优先使用特性,简洁清晰。
-
控制器/Action 上加
[OutputCache]:最常用,支持Duration、PolicyName、VaryByQueryKeys、VaryByHeader等参数 -
Minimal API 使用
WithMetadata:例如() app.MapGet("/api/data", () => "hello").WithMetadata(new OutputCacheAttribute { Duration = 60 }); -
全局策略注册:在
AddOutputCaching()时通过.AddPolicy("my-policy", builder => ...)预定义策略,再用[OutputCache(PolicyName = "my-policy")]复用
常见缓存控制场景与写法
输出缓存会自动设置 Cache-Control 响应头,并根据策略决定是否复用响应。注意以下高频需求写法:
-
缓存 10 分钟:
[OutputCache(Duration = 600)] -
按查询参数区分缓存(如分页):
[OutputCache(VaryByQueryKeys = new[] { "page", "size" })] -
按请求头区分(如 Accept-Language):
[OutputCache(VaryByHeader = "Accept-Language")] -
禁用缓存(绕过):
[OutputCache(NoStore = true, Duration = 0)](仍会走中间件,但不存储) -
仅对匿名用户缓存:需结合
VaryByCustom或自定义IOutputCachePolicy判断HttpContext.User.Identity.IsAuthenticated
调试与验证缓存是否生效
最直接方式是查看响应头:
- 命中缓存时,响应含
X-Output-Cache: Hit(开发环境默认开启该标头) - 未命中或跳过时,可能是策略不匹配、请求方法非 GET/HEAD、状态码非 2xx/304、或有
Set-Cookie等禁止缓存的响应头 - 开发时可启用日志:
builder.Logging.AddConsole().AddFilter("Microsoft.AspNetCore.OutputCaching", LogLevel.Debug);
注意:本地开发默认使用内存缓存,无持久性;生产建议搭配 Redis(需引用 Microsoft.Extensions.Caching.StackExchangeRedis 并注册 AddStackExchangeRedisOutputCaching)。
基本上就这些。Output Caching 设计轻量、语义明确,比手动管理 IMemoryCache 更安全,也比旧 [ResponseCache] 更灵活。关键是理解「策略驱动」和「Vary 机制」——缓存不是简单存 Response.Body,而是按一组维度键(key)来索引和匹配。










