错误请求 (400) Cache-Control 的最佳实践
Best practice of Cache-Control for Bad Request (400)
目前我有以下操作会告诉客户端将响应缓存 1200 秒:
[ResponseCache(Location = ResponseCacheLocation.Client, Duration = 1200)]
[HttpGet("universities")]
public IActionResult GetAllUniversities(string location)
{
if (/*location not found*/)
return BadRequest();
...
return Ok(universities);
}
在响应 header 中,当它 returns Ok (200) 时,我收到以下值:
Cache-Control: private, max-age=1200
正如预期的那样完美。
当我将错误的位置传递给 API 和 API returns BadRequest (400) 时,它也 returns 相同 Cache-Control 值同上。
我的问题是,这是最佳做法吗?还是应该 return no-cache, no-store
而不是 400?如果应该,我如何 return private, max-age=1200
当它是 200 和 return no-cache, no-store
在 .NET Core 中仅用于此特定操作?
您应该在 ASP.NET Core 中使用 Response Caching Middleware,它只缓存 200 个状态代码响应的响应并忽略其他错误响应。
有关如何实施的更多信息,请参阅 - https://docs.microsoft.com/en-us/aspnet/core/performance/caching/middleware?tabs=aspnetcore2x
因为我需要满足以下条件:
- 如果响应代码不是 200,则不 return 响应缓存 header 值。
- Returns
private, max-age=1200
如果响应代码为 200。
- 该解决方案应仅应用于某些控制器操作。
所以我决定创建一个实现 IResultFilter
的属性 class。
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);
}
目前我有以下操作会告诉客户端将响应缓存 1200 秒:
[ResponseCache(Location = ResponseCacheLocation.Client, Duration = 1200)]
[HttpGet("universities")]
public IActionResult GetAllUniversities(string location)
{
if (/*location not found*/)
return BadRequest();
...
return Ok(universities);
}
在响应 header 中,当它 returns Ok (200) 时,我收到以下值:
Cache-Control: private, max-age=1200
正如预期的那样完美。
当我将错误的位置传递给 API 和 API returns BadRequest (400) 时,它也 returns 相同 Cache-Control 值同上。
我的问题是,这是最佳做法吗?还是应该 return no-cache, no-store
而不是 400?如果应该,我如何 return private, max-age=1200
当它是 200 和 return no-cache, no-store
在 .NET Core 中仅用于此特定操作?
您应该在 ASP.NET Core 中使用 Response Caching Middleware,它只缓存 200 个状态代码响应的响应并忽略其他错误响应。
有关如何实施的更多信息,请参阅 - https://docs.microsoft.com/en-us/aspnet/core/performance/caching/middleware?tabs=aspnetcore2x
因为我需要满足以下条件:
- 如果响应代码不是 200,则不 return 响应缓存 header 值。
- Returns
private, max-age=1200
如果响应代码为 200。 - 该解决方案应仅应用于某些控制器操作。
所以我决定创建一个实现 IResultFilter
的属性 class。
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);
}