错误请求的缓存控制的最佳实践(400)

时间:2017-11-03 04:43:50

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

目前,我有以下操作,告诉客户端将响应缓存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

2 个答案:

答案 0 :(得分:1)

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

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

答案 1 :(得分:0)

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

  1. 如果响应代码不是200,请不要返回响应缓存标头值。
  2. 如果响应代码为200,则返回private, max-age=1200
  3. 解决方案应仅适用于某些控制器操作。
  4. 所以我决定创建一个实现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);
    }