Asp.net core 5.0控制器ResponseCache特性的Duration指令被忽略如何解决
问题根源
你在Startup.cs的Configure方法中添加的自定义中间件会强制覆盖所有请求响应的Cache-Control头为30秒,该操作发生在控制器[ResponseCache]特性生成响应头之后,因此控制器的配置会被全局硬编码的规则覆盖,永远不会生效。
解决方案
第一步:移除硬编码缓存规则的自定义中间件
删除Configure方法中的以下代码:
app.Use(async (context, next) => { context.Response.GetTypedHeaders().CacheControl = new Microsoft.Net.Http.Headers.CacheControlHeaderValue() { Public = true, MaxAge = TimeSpan.FromSeconds(30) }; context.Response.Headers[Microsoft.Net.Http.Headers.HeaderNames.Vary] = new string[] { "Accept-Encoding" }; await next(); });
第二步:配置全局默认缓存规则(可选)
如果需要保留30秒作为全局默认缓存规则,改为通过MVC全局过滤器配置,这样控制器的[ResponseCache]特性可以覆盖默认规则。在ConfigureServices中修改控制器注册代码:
services.AddControllers(options => { // 定义全局默认缓存配置 options.Filters.Add(new ResponseCacheAttribute { Duration = 30, Location = ResponseCacheLocation.Any, VaryByHeader = "Accept-Encoding" }); }) .AddNewtonsoftJson(options => options.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore );
第三步:修正控制器的缓存配置
你的接口包含查询参数UserRole,需要显式指定按该参数区分缓存,否则不同角色的用户会拿到同一份缓存结果:
[ResponseCache(Duration = 300, VaryByQueryKeys = new[] { "UserRole" }, VaryByHeader = "Accept-Encoding")] [HttpGet] public IEnumerable<PublicMenu> GetPublicMenu(string UserRole)
验证
修改后再次测试,接口会按照300秒的规则缓存,SQL请求频率会变为每300秒一次,其他接口如果配置了独立的[ResponseCache]也会正常生效。
内容的提问来源于stack exchange,提问作者Davery
相关产品推荐
相关产品推荐

