75

How to disable automatic browser caching from asp.Net mvc application?

Because I am having a problem with caching as it caches all links. But sometimes it redirected to DEFAULT INDEX PAGE automatically which stored it caching and then all the time I click to that link it will redirect me to DEFAULT INDEX PAGE.

So some one know how to manually disable caching option from ASP.NET MVC 4?

6 Answers 6

143

You can use the OutputCacheAttribute to control server and/or browser caching for specific actions or all actions in a controller.

Disable for all actions in a controller

[OutputCacheAttribute(VaryByParam = "*", Duration = 0, NoStore = true)] // will be applied to all actions in MyController, unless those actions override with their own decoration
public class MyController : Controller
{
  // ... 
}

Disable for a specific action:

public class MyController : Controller
{
    [OutputCacheAttribute(VaryByParam = "*", Duration = 0, NoStore = true)] // will disable caching for Index only
    public ActionResult Index()
    {
       return View();
    }
} 

If you want to apply a default caching strategy to all actions in all controllers, you can add a global action filter by editing your global.asax.cs and looking for the RegisterGlobalFilters method. This method is added in the default MVC application project template.

public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
    filters.Add(new OutputCacheAttribute
                    {
                        VaryByParam = "*",
                        Duration = 0,
                        NoStore = true,
                    });
    // the rest of your global filters here
}

This will cause it to apply the OutputCacheAttribute specified above to every action, which will disable server and browser caching. You should still be able to override this no-cache by adding OutputCacheAttribute to specific actions and controllers.

Sign up to request clarification or add additional context in comments.

14 Comments

thanks let me check its great to do this for particular controller only
Ah, yeah, I thought you meant you wanted it on every controller in your application. I'll update my answer to cover both.
I thought it worked, but then I started getting Duration must be a positive number in my controller.
That can't be used with ChildActions
For anyone looking in their code for the RegisterGlobalFilters method, it sometimes exists in App_Start\FilterConfig.cs rather than in Global.asax.cs.
|
28

HackedByChinese is missing the point. He mistook server cache with client cache. OutputCacheAttribute controls server cache (IIS http.sys cache), not browsers (clients) cache.

I give you a very small part of my codebase. Use it wisely.

[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class)]
public sealed class NoCacheAttribute : FilterAttribute, IResultFilter
{
    public void OnResultExecuting(ResultExecutingContext filterContext)
    {
    }

    public void OnResultExecuted(ResultExecutedContext filterContext)
    {
        var cache = filterContext.HttpContext.Response.Cache;
        cache.SetCacheability(HttpCacheability.NoCache);
        cache.SetRevalidation(HttpCacheRevalidation.ProxyCaches);
        cache.SetExpires(DateTime.Now.AddYears(-5));
        cache.AppendCacheExtension("private");
        cache.AppendCacheExtension("no-cache=Set-Cookie");
        cache.SetProxyMaxAge(TimeSpan.Zero);
    }
}

Usage:

/// will be applied to all actions in MyController
[NoCache]
public class MyController : Controller
{
    // ... 
}

Use it wisely as it really disables all client cache. The only cache not disabled is the "back button" browser cache. But is seems there is really no way to get around it. Maybe only by using javascript to detect it and force page or page zones refresh.

8 Comments

This anti caching feature Works perfectly on a commercial web site for More than 3 years. Use fiddler to check the cache headers in the http response.
I understood the point. When using OutputCacheAttribute and setting NoStore=true, browser cache is forbidden (the response headers will look something like Cache-Control: public, no-store, max-age=0 Expires: Mon, 22 Oct 2012 20:19:26 GMT Last-Modified: Mon, 22 Oct 2012 20:19:26 GMT). Therefore, it will prevent server AND browser cache. I know it's curious that it sets public in addition to no-store, but the net effect is no-store and immediate expiration.
you mean it will not cache as immediate expiration will take place ?
It does not work for me either. Browser caching is still happening.
This also worked for me, with or without SetNoStore(). @HackedByChinese built in filter results in Cache-Control: public, no-cache="Set-Cookie", no-store, max-age=0 & Expires + Vary set. This solution results in Cache-Control: no-cache, proxy-revalidate, private, no-cache=Set-Cookie, Expires=-1 and Pragma=no-cache. Since they both work just fine in controlling browser caches, not sure what the issue is.
|
14

We can set cache profile in the Web.config file instead of setting cache values individually in pages to avoid redundant code. We can refer the profile by using the CacheProfile property of the OutputCache attribute. This cache profile will be applied to all pages unless the page/method overrides these settings.

<system.web>
  <caching>
    <outputCacheSettings>
      <outputCacheProfiles>
        <add name="CacheProfile" duration="60" varyByParam="*" />
      </outputCacheProfiles>
    </outputCacheSettings>
  </caching>
</system.web>

And if you want to disable the caching from your particular action or controller, you can override the config cache settings by decorating that specific action method like shown below:

[OutputCache(NoStore = true, Duration = 0, VaryByParam = "*")]
public ActionResult NoCachingRequired()
{
    return PartialView("abcd");
}

Hope this is clear and is useful to you.

Comments

9

If you want to prevent browser caching, you can use this code from ShareFunction

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);
}

1 Comment

The access modifier is required to be protected
5

For on page solution ,Set this in your layout page :

<meta http-equiv="Cache-Control" content="no-cache">
<meta http-equiv="Pragma" content="no-cache">
<meta http-equiv="Expires" content="0">

2 Comments

You can add no-store to make it work in Chrome. <meta http-equiv="Cache-Control" content="non-cache, no-store, must-revalidate">
@Kannan_PK Thanks! I helped me. I used all meta tags listed above, but nothing work. You comment should be included to the answer.
0

To make my answer visible to all, I move my comment to answer for this question.

<meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate">
<meta http-equiv="Pragma" content="no-cache">
<meta http-equiv="Expires" content="0">

This will work in all browsers (IE, Firefox and Chrome as well). Happy to hear my answer worked for you @Joseph Katzman

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.