Prevent Caching in ASP.NET MVC for specific actions using an attribute
Solution 1
To ensure that JQuery isn't caching the results, on your ajax methods, put the following:
$.ajax({
cache: false
//rest of your ajax setup
});
Or to prevent caching in MVC, we created our own attribute, you could do the same. Here's our code:
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
public sealed class NoCacheAttribute : ActionFilterAttribute
{
public override void OnResultExecuting(ResultExecutingContext filterContext)
{
filterContext.HttpContext.Response.Cache.SetExpires(DateTime.UtcNow.AddDays(-1));
filterContext.HttpContext.Response.Cache.SetValidUntilExpires(false);
filterContext.HttpContext.Response.Cache.SetRevalidation(HttpCacheRevalidation.AllCaches);
filterContext.HttpContext.Response.Cache.SetCacheability(HttpCacheability.NoCache);
filterContext.HttpContext.Response.Cache.SetNoStore();
base.OnResultExecuting(filterContext);
}
}
Then just decorate your controller with [NoCache]
. OR to do it for all you could just put the attribute on the class of the base class that you inherit your controllers from (if you have one) like we have here:
[NoCache]
public class ControllerBase : Controller, IControllerBase
You can also decorate some of the actions with this attribute if you need them to be non-cacheable, instead of decorating the whole controller.
If your class or action didn't have NoCache
when it was rendered in your browser and you want to check it's working, remember that after compiling the changes you need to do a "hard refresh" (Ctrl+F5) in your browser. Until you do so, your browser will keep the old cached version, and won't refresh it with a "normal refresh" (F5).
Solution 2
You can use the built in cache attribute to prevent caching.
For .net Framework: [OutputCache(NoStore = true, Duration = 0)]
For .net Core: [ResponseCache(NoStore = true, Duration = 0)]
Be aware that it is impossible to force the browser to disable caching. The best you can do is provide suggestions that most browsers will honor, usually in the form of headers or meta tags. This decorator attribute will disable server caching and also add this header: Cache-Control: public, no-store, max-age=0
. It does not add meta tags. If desired, those can be added manually in the view.
Additionally, JQuery and other client frameworks will attempt to trick the browser into not using it's cached version of a resource by adding stuff to the url, like a timestamp or GUID. This is effective in making the browser ask for the resource again but doesn't really prevent caching.
On a final note. You should be aware that resources can also be cached in between the server and client. ISP's, proxies, and other network devices also cache resources and they often use internal rules without looking at the actual resource. There isn't much you can do about these. The good news is that they typically cache for shorter time frames, like seconds or minutes.
Solution 3
All you need is:
[OutputCache(Duration=0)]
public JsonResult MyAction(
or, if you want to disable it for an entire Controller:
[OutputCache(Duration=0)]
public class MyController
Despite the debate in comments here, this is enough to disable browser caching - this causes ASP.Net to emit response headers that tell the browser the document expires immediately:
Solution 4
In the controller action append to the header the following lines
public ActionResult Create(string PositionID)
{
Response.AppendHeader("Cache-Control", "no-cache, no-store, must-revalidate"); // HTTP 1.1.
Response.AppendHeader("Pragma", "no-cache"); // HTTP 1.0.
Response.AppendHeader("Expires", "0"); // Proxies.
Solution 5
Here's the NoCache
attribute proposed by mattytommo, simplified by using the information from Chris Moschini's answer:
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
public sealed class NoCacheAttribute : OutputCacheAttribute
{
public NoCacheAttribute()
{
this.Duration = 0;
}
}
Related videos on Youtube
JavaScript Developer
Updated on July 31, 2020Comments
-
JavaScript Developer almost 4 years
I have an ASP.NET MVC 3 application. This application requests records through jQuery. jQuery calls back to a controller action that returns results in JSON format. I have not been able to prove this, but I'm concerned that my data may be getting cached.
I only want the caching to be applied to specific actions, not for all actions.
Is there an attribute that I can put on an action to ensure that the data does not get cached? If not, how do I ensure that the browser gets a new set of records each time, instead of a cached set?
-
Admin about 12 yearsIf you are guessing that something is being cached, then I recommend that you read up on cache control mechanisms here: w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9
-
-
Obi Wan over 10 yearsI tried everything in the above solution and it does not work for me.
-
Josh over 10 yearsIt's my understanding (and I'm no jQuery expert) that cache:false only makes jQuery tack on to the query string a changing value to "trick" the browser into thinking the request is for something else. In theory, this means the browser would still cache the results, just wouldn't use the cached results. Should be more efficient on the client to disable caching via response headers.
-
Jaguir almost 10 yearsIt is impossible to force the browser to disable caching. The best you can do is provide suggestions that most browsers will honor, usually in the form of headers or meta tags. This decorator attribute will disable the .NET server caching and also add the header
Cache-Control:public, no-store, max-age=0
. It does not add meta tags. If desired, those can be added manually in the view. -
Ramesh over 9 yearsWorked only on controller level and not on action level.
-
Keith Ketterer about 9 yearsIE8 still renders the cached version of the page when the back button is clicked using only Duration=0 on a Controller Action. Using NoStore = true along with Duration = 0 (see Jared's answer) fixed the behavior in my case.
-
micahhoover about 9 yearsFor some reason MVC 3 doesn't just let you set the duration to 0. You have to add these annotations ... thanks for the workaround!
-
ta.speot.is about 9 yearsThis has the somewhat curious behavior of setting
Cache-Control
topublic
-
Gone Coding about 9 yearsI can understand why you would use
NoStore = true
andDuration = 0
(which I have used successfully, thanks), but what additional effect wouldVaryByParam = "None"
have as the other two options affect all requests regardless of parameter? -
Jaguir about 9 yearsI don't think it's required in MVC, I was just being explicit. I do remember that in ASP.NET web forms and user controls, either this attribute or the VaryByControl attribute is required.
-
Mark Rucker almost 9 yearsWarning, I've been messing with this today. From what I can tell this attribute does not modify Cache-Control if
<outputCache enableOutputCache="false" />
. In the case that OutputCache has been explicitly disabled you'll need to set the CacheControl headers manually (either in the Action or by using [mattytommo's answer][stackoverflow.com/a/10011896/1066291]). -
usr-local-ΕΨΗΕΛΩΝ almost 9 yearsI would upvote including such an attribute in the official ASP.NET package :-)
-
Ted Nyberg over 8 years@usr-local-ΕΨΗΕΛΩΝ There is no need for such an attribute, see other answers involving OutputCache attribute instead.
-
mattytommo over 8 years@TedNyberg See the last comment on the other answer from Mark Rucker, the built in attribute doesn't offer complete cache disabling.
-
Frédéric over 8 years
max-age=0
has never meant 'cache disabled'. This does only mean that response content is to be considered immediately stale, but a cache is allowed to cache it. Browsers should validate freshness of cached stale content before using it, but it is not mandatory unless the additional directivemust-revalidate
is specified. -
Frédéric over 8 years
no-store
is not guaranteed to be enough. The response may still be cached in a volatile cache (as ram memory).max-age=0
is neither sufficient alone or withno-store
. It does not prevent caching, it just mark the content as immediately stale. It may still be cached, but caches are invited to revalidates it before use (but are allowed to serve it without revalidation). -
Frédéric over 8 years
max-age=0
has never meant 'cache disabled'. This does only mean that response content is to be considered immediately stale, but a cache is allowed to cache it. Browsers should validate freshness of cached stale content before using it, but it is not mandatory unless the additional directivemust-revalidate
is specified. -
Frédéric over 8 years@TedNyberg,
OutputCache
does mix http cache control with server output cache (especially with itvary
handling), does not honor the full semantics of http caching and does allow real deactivation of http caching (no-cache
directive) by specifyingLocation=OutputCacheLocation.None
(orServer
). In short,outputcache
is plainly broken when it is about http caching. We should only use it for controlling server output caching (which is broken by itself on IIS for loads of other reasons anyway). -
Frédéric over 8 yearsFor completeness, the minimal and more appropriate directive is
no-cache
, which still allows caching but mandate to revalidates on origin server before any use. To avoid even revalidated caching you have to addno-store
along withno-cache
. (no-store
alone is plainly wrong because volatile caches are allowed to cache content marked asno-store
.) -
Sam over 8 yearsPity it does not even compile with asp.net 5 :(
-
mattytommo over 8 years@Sam Really? I haven't tried yet. What's the issue?
-
Sam over 8 years@mattytommo No worries, I used [ResponseCache(NoStore = true)] instead, it works like charm and is build-in.
-
Frédéric over 8 years
-
Frédéric over 8 years@Sam
no-store
alone is wrong because volatile caches are allowed by http spec to cache content marked as no-store. You may have issues in some browsers. -
Sam over 8 years@Frédéric what is recommended instead of using NoStore?
-
Frédéric over 8 years@Sam,
no-cache
. ButOutputCache
does not allow to control it directly, you have to useLocation
withOutputCacheLocation
valueNone
orServer
. This still does not really forbid caching, but it forces the client to at least check with the server its cached response is still valid. -
kristianp over 7 years@Frédéric, the section of the spec you point to says that caches cannot cache no-store content: The "no-store" response directive indicates that a cache MUST NOT store any part of either the immediate request or response.
-
SAR over 7 years@Jaguire for example i need to disable for the login page, do i need to place in account controller head or in each and every action or where!?
-
Jaguir over 7 years@SAR Placing it on your login controller or its actions should suffice.
-
SAR over 7 years@Jaguire i did put the code on top of the Account Controller which login is located there, again in google chrome i login and with out loging out i close the IE then again when i try IE i get the page with request for login
-
Jaguir over 7 years@SAR That sounds like your issue is beyond simple caching. Maybe with your session or cookies? Start a question detailing your issue and you will get better help.
-
Jeff almost 7 yearsFor ASP.NET Core use: '[ResponseCache(NoStore = true, Duration = 0)]'