I'm trying to set cache headers in ASP.NET MVC Web API, but the response from IIS suggests that the CacheControl values set are being ignored.
My original assumption was that I was using the EnableCorsAttribute in System.Web.Http.Cors, which is necessary in this use case. However, even without that attribute, the response Cache-Control header is still 'private'.
Is there something I am doing wrong here?
// GET api/<version>/content
// [EnableCors(origins: "*", headers: "*", methods: "*")]
public HttpResponseMessage Get(HttpRequestMessage request)
{
int cacheMaxAgeSeconds;
string cacheMaxAgeString = request.GetQueryString("cache-max-age") ?? request.GetQueryString("cache-max-age-seconds");
string rawUri = request.RequestUri.ToString();
try
{
cacheMaxAgeSeconds = cacheMaxAgeString == null ? Config.ApiCacheControlMaxSeconds : int.Parse(cacheMaxAgeString);
}
catch (Exception ex)
{
cacheMaxAgeSeconds = Config.ApiCacheControlMaxSeconds;
//...
}
try
{
//...
var response = new HttpResponseMessage(HttpStatusCode.OK)
{
Content = new StringContent("...", Encoding.UTF8, "application/json")
};
response.Headers.CacheControl = new CacheControlHeaderValue
{
Public = true,
MaxAge = TimeSpan.FromSeconds(cacheMaxAgeSeconds)
};
return response;
}
catch (Exception apiEx)
{
//...
}
}
Response
HTTP/1.1 200 OK
Cache-Control: private
Content-Type: application/json; charset=utf-8
Date: Thu, 23 Jul 2015 10:53:17 GMT
Server: Microsoft-IIS/7.5
Set-Cookie: ASP.NET_SessionId=knjh4pncbrhad30kjykvwxyz; path=/; HttpOnly
X-AspNet-Version: 4.0.30319
X-Powered-By: ASP.NET
Content-Length: 2367
Connection: keep-alive
Without the cache control header the browser requests the resource every time it loads a new(?) page.
private. The private response directive indicates that the response can be stored only in a private cache (e.g. local caches in browsers). You should add the private directive for user-personalized content, especially for responses received after login and for sessions managed via cookies.
Code below sets "cache-control: public, max-age=15" correctly in vanilla WebApi application (System.Web.Http 4.0.0.0). So... it's probably not the WebApi itself that causes the issue.
You may have some magic in your project that changes cache settings (think of global action filters or something similar). Or maybe you are going through proxy which rewrites HTTP headers.
public HttpResponseMessage Get()
{
var content = new JavaScriptSerializer().Serialize(new { foo = "bar" });
var response = new HttpResponseMessage(HttpStatusCode.OK)
{
Content = new StringContent(content, Encoding.UTF8, "application/json")
};
response.Headers.CacheControl = new CacheControlHeaderValue
{
Public = true,
MaxAge = TimeSpan.FromSeconds(15)
};
return response;
}
// returns in the response: "Cache-Control: public, max-age=15"
The answer, having picked this up some weeks later:
Cache-Control header appears to be set to 'private' when running debug builds. The issue goes away when I run with a release build.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With