ResponseCaching中间件仅缓存200状态码的GET/HEAD请求,需注册AddResponseCaching()并按序启用UseResponseCaching(),且不支持跨服务器、带Authorization或Set-Cookie的请求。

ASP.NET Core 的 ResponseCaching 中间件只对状态码 200 的 GET/HEAD 请求生效,且缓存存在内存中——跨服务器、带 Authorization 头、含 Set-Cookie 或已写入响应体的请求,一律不缓存。
ResponseCaching 中间件必须注册并启用
漏掉任一环节,[ResponseCache] 特性完全无效:
-
builder.Services.AddResponseCaching()必须在Program.cs服务注册阶段调用 -
app.UseResponseCaching()必须在app.UseRouting()之后、app.MapControllers()之前调用(顺序错位会导致中间件被跳过) - 若项目启用了 CORS,
app.UseCors()应放在UseResponseCaching()之后,否则缓存头可能被拦截或覆盖
[ResponseCache] 特性的常见误配参数
这个特性最终生成的是 HTTP 响应头,但很多参数组合实际无效或相互冲突:
-
Duration = 0会生成Cache-Control: no-cache,但中间件仍可能尝试缓存(需配合NoStore = true才真正禁用) -
Location = ResponseCacheLocation.None和NoStore = true必须同时设,否则浏览器仍可能本地缓存 -
Vary参数(如Vary = "User-Agent")必须与真实返回内容差异一致;若后端没做差异化处理,只加Vary会导致缓存碎片化、命中率暴跌 -
Duration是秒数,不是毫秒——设成60000意味着缓存 16 小时,不是 1 分钟
手动设置响应头比特性更灵活,但也更易出错
绕过 [ResponseCache] 直接操作 HttpContext.Response 适合动态策略,但要注意类型和时机:
- 必须用
HttpContext.Response.GetTypedHeaders().CacheControl设置强类型对象,而不是直接拼字符串到Headers["Cache-Control"](后者容易格式错误) - 设置
Vary时,必须用Headers["Vary"] = new string[] { "Accept-Encoding" },不能传单个字符串 - 所有响应头必须在
WriteAsync或Result返回前完成设置;一旦响应开始写入,再改头会抛InvalidOperationException - 如果控制器方法返回
IActionResult,建议统一在 Action 内部设置,避免依赖过滤器顺序
ResponseCaching 是内存级、单机、无共享的
它不解决分布式部署下的缓存一致性问题:
- 两台服务器部署同一 API,用户 A 请求打到 Server1 缓存了结果,用户 B 同样请求打到 Server2,仍会重新执行逻辑
- 无法监听数据库变更自动失效,也不支持文件或 SQL Server 依赖项(那是旧版 ASP.NET Web Forms 的
OutputCache功能) - 想跨实例共享或支持主动失效,必须上 Redis + 自定义中间件,或把缓存前置到 CDN 层
真正需要“服务端响应缓存”的场景,往往得搭配 IMemoryCache 或 IDistributedCache 手动控制数据层,而不是依赖 ResponseCaching 中间件——后者更适合静态接口、低频变动的聚合页,且前提是清楚它的边界在哪里。


















