locked
Stopping browser caching of web pages RRS feed

  • Question

  • User-1466445078 posted

    Hi,

    I'm having a problem with browser caching of my site. I've built a simple CMS website that allows the admin user to update content/pages (stored in a database) - but when an update is made (in the back end) and you revisit the page (on the front end) it still shows the old (un-updated content) - if you refresh your browser the new content then displays.

    I used to have the same problem in old Classic ASP pages I made and for those I added the following to the top of each page:

    <%
    Response.Expires = 0
    Response.Expiresabsolute = Now() - 1
    Response.AddHeader "Pragma", "no-cache"
    Response.AddHeader "cache-control", "no-store" 
    Response.AddHeader "cache-control", "private, no-cache, must-revalidate" 
    Response.CacheControl = "no-cache"
    %>

    This seemed to do the trick and make the browsers show the latest content.

    Is there a nice way of doing this in ASP.NET Web Pages (cshtml). I found this thread on the forum http://forums.asp.net/t/1013531.aspx?How+to+prevent+browser+and+proxy+caching+of+web+pages but it's a bit old 2006 - 2010 and each reply suggests something different, one suggests:

    Response.AppendHeader("Cache-Control", "no-cache; private; no-store; must-revalidate; max-stale=0; post-check=0; pre-check=0; max-age=0"); // HTTP 1.1
    Response.AppendHeader("Pragma", "no-cache"); // HTTP 1.1
    Response.AppendHeader("Keep-Alive", "timeout=3, max=993"); // HTTP 1.1
    Response.AppendHeader("Expires", "Mon, 26 Jul 1997 05:00:00 GMT"); // HTTP 1.1

    which looks pretty similar to my old Classic ASP code.

    Someone else suggested:

    Response.Cache.SetExpires(DateTime.UtcNow.AddMinutes(-1))
    Response.Cache.SetCacheability(HttpCacheability.NoCache)
    Response.Cache.SetNoStore()

    Can anyone suggest which one I should be using - I'm concerned about a trial and error approach (i.e. trying the various suggestions in the other post) as I'm not sure what harm I might do to the site. Also I'm not sure where of the best place to put this code, should I put it in my /Shared/_Layout.cshtml master layout page, or one each content page or in the _AppStart.cshtml file?

    I did also try adding the following to the web.config file:

    <configuration>
       <system.webServer>
          <staticContent>
             <clientCache cacheControlMode="DisableCache" />
          </staticContent>
       </system.webServer>
    </configuration>

    But that didn't make any difference.

    Any help will be gratefully received.

    Many thanks.

    Friday, September 12, 2014 10:49 AM

Answers

  • User-821857111 posted

    I used to have the same problem in old Classic ASP pages I made and for those I added the following to the top of each page:

    <%
    Response.Expires = 0
    Response.Expiresabsolute = Now() - 1
    Response.AddHeader "Pragma", "no-cache"
    Response.AddHeader "cache-control", "no-store" 
    Response.AddHeader "cache-control", "private, no-cache, must-revalidate" 
    Response.CacheControl = "no-cache"
    %>

    This seemed to do the trick and make the browsers show the latest content.

    Do the same in ASP.NET (amending language, of course). The reason that answers to this question often show a variety of methods is because different browsers behave differently. In other words, there is no tidy one-liner in the ASP.NET framework.

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Friday, September 12, 2014 11:27 AM
  • User-821857111 posted

    Ideally I'd like to have a dynamic date in the Expires header (i.e. one day before, rather than a fixed date)

    Response.AppendHeader("Expires", DateTime.Now.AddDays(-1).ToString("r"));

    Is there any problems with using such code?

    No. Top of your layout page is fine.

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Monday, September 15, 2014 5:59 AM

All replies

  • User-821857111 posted

    I used to have the same problem in old Classic ASP pages I made and for those I added the following to the top of each page:

    <%
    Response.Expires = 0
    Response.Expiresabsolute = Now() - 1
    Response.AddHeader "Pragma", "no-cache"
    Response.AddHeader "cache-control", "no-store" 
    Response.AddHeader "cache-control", "private, no-cache, must-revalidate" 
    Response.CacheControl = "no-cache"
    %>

    This seemed to do the trick and make the browsers show the latest content.

    Do the same in ASP.NET (amending language, of course). The reason that answers to this question often show a variety of methods is because different browsers behave differently. In other words, there is no tidy one-liner in the ASP.NET framework.

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Friday, September 12, 2014 11:27 AM
  • User-1466445078 posted

    Hi Mike,

    Thanks for the speedy reply. I'll give it a go - where would I put the code, at the top of my master layout page or on each individual page - or is there a way to add it globally to all pages on the site (i.e. in AppStart.cshtml)

    Many thanks,

    Friday, September 12, 2014 11:39 AM
  • User895691971 posted

    Yes, you should put it inside the Global pages that would be executed throughout the website, in Web Pages you would be using the _AppStart.cshtml page. 

    If you want to remove caching for a particular page, or a set pages only then you should add this code to those pages. If you want to remove such function from all of the pages (entire site) then add it to Master or Global pages, in Web Pages framework _AppStart.cshtml (as mentioned above). 

    Sunday, September 14, 2014 2:46 AM
  • User-821857111 posted

    You can't put that code in App_Start. It doesn't have a Response property. You have to use Context.Response there:

        Context.Response.Cache.SetExpires(DateTime.UtcNow.AddDays(-1));
        Context.Response.Cache.SetAllowResponseInBrowserHistory(false);
        Context.Response.Cache.SetRevalidation(HttpCacheRevalidation.AllCaches);
        Context.Response.Cache.SetCacheability(HttpCacheability.NoCache);
        Context.Response.Cache.SetNoStore();

    The above is basically an ASP.NET translation of your classic ASP code. Some properties don't have a one-to-one mapping. So my suggestion to just copy it wouldn't work.

    Sunday, September 14, 2014 4:52 AM
  • User-1466445078 posted

    Hi,

    Thank you both your responses.

    I tried the "Context.Response.Cache...." code in the AppStart.cshtml file but it doesn't seem to stop the browser from caching the page. I did some tested with Chrome Developer Tools and could see it was using a cached version of the page.

    The code I've used, which seems to work is the following which I've added to the top of my master layout page (/Shared/_Layout.cshtml):

    @{ 
    Response.AppendHeader("Cache-Control", "no-cache; private; no-store; must-revalidate; max-stale=0; post-check=0; pre-check=0; max-age=0"); // HTTP 1.1
    Response.AppendHeader("Pragma", "no-cache"); // HTTP 1.1
    Response.AppendHeader("Keep-Alive", "timeout=3, max=993"); // HTTP 1.1
    Response.AppendHeader("Expires", "Fri, 31 Jan 2014 05:00:00 GMT"); // HTTP 1.1
    }

    Ideally I'd like to have a dynamic date in the Expires header (i.e. one day before, rather than a fixed date) but other than that it seems to work. The page isn't cached and a new/updated version is fetched each time.

    Is there any problems with using such code?

    Thanks again for taking the time to respond, it's much appreciated.

    Monday, September 15, 2014 5:21 AM
  • User-821857111 posted

    Ideally I'd like to have a dynamic date in the Expires header (i.e. one day before, rather than a fixed date)

    Response.AppendHeader("Expires", DateTime.Now.AddDays(-1).ToString("r"));

    Is there any problems with using such code?

    No. Top of your layout page is fine.

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Monday, September 15, 2014 5:59 AM
  • User-1466445078 posted

    Hi Mike,

    Thanks, that works great.

    Thanks for your help.

    Monday, September 15, 2014 6:41 AM