10

I need to expire my content so that when the user hits the browsers navigation(back) button the controller action gets executed. So instead of adding the following code to each and every
action is there a better way to do it.

HttpContext.Response.Expires = -1;
HttpContext.Response.Cache.SetNoServerCaching();
Response.Cache.SetAllowResponseInBrowserHistory(false);
Response.CacheControl = "no-cache";
Response.Cache.SetNoStore();
kolhapuri
  • 1,581
  • 4
  • 20
  • 31

3 Answers3

29

You can put this logic into an ActionFilter meaning that rather than adding the above code to each of your Action methods in your controller, you can just decorate the Action method with your custom filter. Or if it applies to all Action methods in a Controller you can apply the attribute to the whole Controller.

Your ActionFilter will be something like this:

public class MyExpirePageActionFilterAttribute : System.Web.Mvc.ActionFilterAttribute
    {
        public override void OnActionExecuted(System.Web.Mvc.ActionExecutedContext filterContext)
        {
            base.OnActionExecuted(filterContext);

            filterContext.HttpContext.Response.Expires = -1;
            filterContext.HttpContext.Response.Cache.SetNoServerCaching();
            filterContext.HttpContext.Response.Cache.SetAllowResponseInBrowserHistory(false);
            filterContext.HttpContext.Response.CacheControl = "no-cache";
            filterContext.HttpContext.Response.Cache.SetNoStore();

        }
    }

See this article for more information.

If you want this on all Actions of your entire application, you can actually apply an ActionFilter to all Actions using a global ActionFilter set up in your Global.asax:

protected void Application_Start()
{
    AreaRegistration.RegisterAllAreas();

    GlobalFilters.Filters.Add(new MyExpirePageActionFilterAttribute());

    RegisterGlobalFilters(GlobalFilters.Filters);
    RegisterRoutes(RouteTable.Routes);
}
Swaff
  • 13,548
  • 4
  • 26
  • 26
  • Yes I agree that I need to create an ActionFilter. And I was in process of creating that. So I guess that approach is validated based on your responses. What I want a feedback on was is what goes inside theat filter. Would the 5 lines that I have make sense or is there a better way to do it? Thanks. – kolhapuri Mar 18 '11 at 15:03
  • @kolhapuri I see, check out this [link here](http://stackoverflow.com/questions/1906163/how-to-force-a-page-refresh-while-pressing-the-back-button-in-mac-safari) which describes someone wanting to prevent Safari from caching the previous page. – Swaff Mar 18 '11 at 15:13
  • Came across this today and it fixed a problem I was having! – Don Zacharias Aug 06 '12 at 20:30
1

You can write your own ActionFilter and put the code in there.

If you don't want to decorate all of your action methods with this filter, then you can register it as a global action filter: http://weblogs.asp.net/gunnarpeipman/archive/2010/08/15/asp-net-mvc-3-global-action-filters.aspx

Brian Ball
  • 12,268
  • 3
  • 40
  • 51
0

You could put it in an HTTP Module.

Greg B
  • 14,597
  • 18
  • 87
  • 141