views:

428

answers:

2

Hi

I have a web application that fetches a lot of content via ajax. For example when a user edits some data, the browser will send the changes using an ajax post and then do an ajax get to get fresh content and replace an existing div on the page with that content. This was working just find with MVC1, but in MVC2 I would get inconsistent results.

I've found that MVC1 by default included an Expires item in the response headers set to the current time, but in MVC2 the Expires header is missing. This is a problem with some browsers (IE8) actually using the cached version of the ajax get instead of the fresh version.

To deal with the problem I created a simple ActionFilterAttribute that sets the reponse cache to NoCache (see below), which works, but it seems kind of sillly to decorate every controller with this attribute. Is there a global way to set this for every controller?

Is this a bug in MVC2 and it really should be setting the expires on every ActionResult/view/page? Don't most MVC programs deal with data entry where stale data is a very bad thing?

Thanks

Dan


public class ResponseNoCachingAttribute : ActionFilterAttribute
{
    public override void OnResultExecuted(ResultExecutedContext filterContext)
    {
        base.OnResultExecuted(filterContext);

        filterContext.HttpContext.Response.Cache.SetCacheability(System.Web.HttpCacheability.NoCache);
    }
}
+2  A: 

Have you tried adding the following attribute to your controller?

[OutputCache(Location = OutputCacheLocation.None)]
Richard Ev
Yes, that will work. I didn't notice that attribute before. It still seems kind of silly that you have to put that attribute on every controller instead of having a global setting somewhere. Thanks.
Dan
You could declare an appropriately-named abstract base class controller with the attribute, and have all of your controllers inherit from that.
Richard Ev
A: 

I have faced a similar situation this week. Especially the IE8 part. I have to admit. I tried adding timestamps to the URL(the traditional workaround) but it simply makes the routing definitions look ugly.

After quite some time I ended up using this.

[OutputCache(NoStore = true, Location = System.Web.UI.OutputCacheLocation.None)]

conqenator