【问题标题】:Best practice of Cache-Control for Bad Request (400)错误请求的缓存控制最佳实践 (400)
【发布时间】:2017-11-03 04:43:49
【问题描述】:

目前我有以下操作,它将告诉客户端将响应缓存 1200 秒:

[ResponseCache(Location = ResponseCacheLocation.Client, Duration = 1200)]
[HttpGet("universities")]
public IActionResult GetAllUniversities(string location)
{
    if (/*location not found*/)
      return BadRequest();

    ...
    return Ok(universities);
}

在响应头中,当它返回 Ok (200) 时,我收到了以下值:

Cache-Control: private, max-age=1200

正如预期的那样完美。

当我将错误的位置传递给 API 并且 API 返回 BadRequest (400) 时,它也会返回与上述相同的 Cache-Control 值。

我的问题是,这是最佳做法吗?还是应该返回 no-cache, no-store 而不是 400?如果应该,我如何在 200 时返回 private, max-age=1200 并在 .NET Core 中仅针对此特定操作返回 no-cache, no-store

【问题讨论】:

    标签: c# asp.net-web-api asp.net-core cache-control


    【解决方案1】:

    您应该使用 ASP.NET Core 中的响应缓存中间件,它只缓存 200 个状态代码响应的响应并忽略其他错误响应。

    有关如何实施的更多信息,请参阅 - https://docs.microsoft.com/en-us/aspnet/core/performance/caching/middleware?tabs=aspnetcore2x

    【讨论】:

      【解决方案2】:

      因为我需要满足以下条件:

      1. 如果响应码不是 200,则不返回响应缓存标头值。
      2. 如果响应码为 200,则返回 private, max-age=1200
      3. 该解决方案应仅应用于某些控制器操作。

      所以我决定创建一个属性类来实现IResultFilter

      public sealed class PrivateCacheControlResultFilterAttribute : Attribute, IResultFilter
      {
          public void OnResultExecuted(ResultExecutedContext context)
          {
          }
      
          public void OnResultExecuting(ResultExecutingContext context)
          {
              context.HttpContext.Response.OnStarting(state =>
              {
                  var httpContext = ((ResultExecutingContext)state).HttpContext;
      
                  if (httpContext.Response.StatusCode == 200)
                      httpContext.Response.GetTypedHeaders().CacheControl = new CacheControlHeaderValue
                      {
                          Private = true,
                          MaxAge = TimeSpan.FromSeconds(1200)
                      };
                  return Task.CompletedTask;
              }, context);
          }
      }
      

      然后在GetAllUniversities 操作上使用这个新属性。

      [PrivateCacheControlResultFilter]
      [HttpGet("universities")]
      public IActionResult GetAllUniversities(string location)
      {
          if (/*location not found*/)
            return BadRequest();
      
          ...
          return Ok(universities);
      }
      

      【讨论】:

        猜你喜欢
        • 2015-02-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-05-31
        • 1970-01-01
        • 2021-05-07
        相关资源
        最近更新 更多