responsecaching中间件默认不生效,必须同时满足注册服务(addresponsecaching)、正确启用顺序(useresponsecaching在userouting后、mapcontrollers前)及请求条件(仅200状态码的get/head,无authorization/set-cookie等),缺一即导致[responsecache]失效。

ResponseCaching 中间件在 ASP.NET Core 中默认不生效,漏掉注册、启用顺序或请求条件中的任意一环,[ResponseCache] 特性就只是个装饰。
为什么 [ResponseCache] 加了却没缓存?
最常见原因是中间件链配置缺失或错位。它不是“加个特性就自动跑”,而是依赖两个硬性前提:
-
builder.Services.AddResponseCaching()必须在Program.cs的服务注册阶段调用,且不能放在AddControllers()之后 -
app.UseResponseCaching()必须在app.UseRouting()之后、app.MapControllers()(或app.UseEndpoints())之前 —— 顺序颠倒会导致中间件被跳过,[ResponseCache]完全静默 - 若项目启用了 CORS,
app.UseCors()必须放在UseResponseCaching()之后,否则响应头可能被覆盖或丢弃
ResponseCaching 只缓存哪些请求?
它有非常严格的白名单机制,不符合任一条件的请求直接绕过缓存逻辑:
- 仅处理
200 OK状态码;404、302、500等一律不缓存 - 只接受
GET和HEAD方法;POST、PUT、DELETE被无视 - 拒绝带
Authorization头的请求(含 Bearer Token、Basic Auth) - 拒绝响应中已包含
Set-Cookie头的请求(防会话污染) - 拒绝响应体已开始写入(如
WriteAsync已触发)的请求
[ResponseCache] 参数怎么配才真正生效?
这个特性生成的是 HTTP 响应头,但很多参数组合实际无效,甚至相互抵消:
-
Duration = 0会输出Cache-Control: no-cache,但中间件仍可能尝试缓存 —— 必须同时设NoStore = true才彻底禁用 -
Location = ResponseCacheLocation.None单独使用无效;浏览器仍可能本地缓存,必须搭配NoStore = true -
Vary是双刃剑:比如Vary = "User-Agent",后端若没按 UA 返回不同内容,只会导致缓存碎片化、命中率暴跌 -
Duration单位是秒,不是毫秒 —— 设成60000是缓存 16 小时,不是 1 分钟
手动设置响应头比特性更灵活,但也更易出错
适合需要动态策略(如按用户角色/请求参数差异化缓存)的场景,但要注意类型和时机:
- 必须用
HttpContext.Response.GetTypedHeaders().CacheControl设置强类型对象,不要拼字符串到Headers["Cache-Control"](格式错误难调试) - 设
Vary时,必须用Headers["Vary"] = new string[] { "Accept-Encoding" },传单个字符串会失败 - 所有响应头必须在
WriteAsync或IActionResult返回前完成;一旦响应开始写入,再改头会抛InvalidOperationException - 如果控制器方法返回
IActionResult,建议统一在 Action 内部设置,避免依赖过滤器执行顺序
ResponseCaching 是纯内存、单机、无共享的 —— 它不解决分布式部署下的缓存一致性问题,也不监听数据库变更。你得自己补上 Redis 或事件总线来联动失效,否则两台服务器上缓存内容天然不同步。











