Currently I have the following action which will tell the client to cache the response for 1200 seconds:
[ResponseCache(Location = ResponseCacheLocation.Client, Duration = 1200)]
[HttpGet("universities")]
public IActionResult GetAllUniversities(string location)
{
if (/*location not found*/)
return BadRequest();
...
return Ok(universities);
}
In the response header, when it returns Ok (200), I received the following value:
Cache-Control: private, max-age=1200
Which is perfect as expected.
When I passed the wrong location to the API and the API returns BadRequest (400), it also returns the same Cache-Control value as above.
My question is, is this the best practice? Or should it return no-cache, no-store
instead for 400? If it should, how do I return private, max-age=1200
when it's 200 and return no-cache, no-store
in .NET Core for this particular action only?
Because I need to satisfy the following conditions:
private, max-age=1200
if the response code is 200.So I decided to create an attribute class that implements IResultFilter
instead.
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);
}
}
Then use this new attribute on the GetAllUniversities
action.
[PrivateCacheControlResultFilter]
[HttpGet("universities")]
public IActionResult GetAllUniversities(string location)
{
if (/*location not found*/)
return BadRequest();
...
return Ok(universities);
}