Reputation: 4042
This question is related to my other question.
I have an MVC application with caching disabled for all controller actions. I do this by setting cache response headers in Application_BeginRequest
:
protected void Application_BeginRequest()
{
HttpContext.Current.Response.Cache.SetExpires(DateTime.UtcNow.AddDays(-1));
HttpContext.Current.Response.Cache.SetValidUntilExpires(false);
HttpContext.Current.Response.Cache.SetRevalidation(HttpCacheRevalidation.AllCaches);
HttpContext.Current.Response.Cache.SetCacheability(HttpCacheability.NoCache);
HttpContext.Current.Response.Cache.SetNoStore();
}
There is single controller action for which I do want caching enabled. I have decorated this action with the OutputCache
attribute:
[OutputCache(Duration = 300, VaryByParam = "id")]
What happens now for this action? Does it get cached because of the OutputCache attribute, or is it not cached because of the response headers?
-- EDIT --
As it seems, the response headers take preference. So my question becomes: how can I enable cache for single controller actions? Overwrite the response headers again?
Upvotes: 8
Views: 1533
Reputation: 4042
The response headers enforce the cache control. The solution was not to set response headers for controller actions that require caching. Instead of using OutputCache
, I'm now using a custom cache attribute that also sets an ISCACHED
key in the request items dictionary. The code snippet from my question was changed to this:
protected void Application_EndRequest()
{
if (HttpContext.Current.Items["ISCACHED"] == null)
{
var cache = HttpContext.Current.Response.Cache;
cache.SetCacheability(HttpCacheability.NoCache);
cache.SetNoStore();
cache.SetExpires(DateTime.Now.AddDays(-1));
}
}
I had to move this from BeginRequest
to EndRequest
, to allow actions to set the ISCACHED
request item first. If it is set, a controller already handled caching for this request, otherwise caching is disabled.
Upvotes: 2
Reputation: 1062780
The two things are separate; the response cache is primarily looking at what the client sees - what they will use without hitting the server, or what modified-date they will send up to the server.
OutputCache, however, is focused at the server; the request will still happen (unlike something cached at the client), but it is possible (hopefully likely) that your method won't be called: instead, the cached version will be returned.
So: it is not cached at the client; a HTTP request is made, and (for requests within 5 minutes, for the same id
, memory permitting) the cached version is returned from the server (typically reducing IO and CPU load at the server). Make sense?
Upvotes: 7