Introduction
Today, as webmaster of www.doblered.net (a tennis events related site) I've received an email saying that some information is not updated on iPhone/iPad. On PC's and Mac's all works fine. Searching in google, I've found this question in a forum: http://stackoverflow.com/questions/12506897/is-safari-on-ios-6-caching-ajax-results. So, working in a solution to this problem, here is my tip, that worked for me on ASP.NET with MVC3.
Background
Solutions given in the thread implies to alter all my actions affected in many of my controllers, so I need a global solution. The GlobalFilters
class is very useful to acomplish this.
Using the code
The first thing to do is create a class inherited from
ActionFilterAttribute
class with this code:
Public Class GlobalActionFiltersAttribute
Inherits ActionFilterAttribute
Public Overrides Sub OnActionExecuting(filterContext As System.Web.Mvc.ActionExecutingContext)
If filterContext.HttpContext.Request.RequestType.ToLower.Equals("post") Then
filterContext.HttpContext.Response.Cache.SetNoStore()
filterContext.HttpContext.Response.Cache.SetCacheability(HttpCacheability.NoCache)
End If
MyBase.OnActionExecuting(filterContext)
End Sub
End Class
The final step is adding following code to Application_Start
sub on global.asax.vb file:
GlobalFilters.Filters.Add(New GlobalActionFiltersAttribute())
As result, all response header on action requested as post in our project will look like this:
Cache-Control | no-cache, no-store |
Content-Encoding | gzip |
Content-Length | 1426 |
Content-Type | text/html; charset=utf-8 |
Date | Mon, 19 Nov 2012 11:23:56 GMT |
Expires | -1 |
Pragma | no-cache |
Server | Microsoft-IIS/7.0 |
Vary | Accept-Encoding |
X-Powered-By | ASP.NET |
Points of Interest
It's obvious that even on post requests we must specify that response must not be cached. This fact is oppossed to http specifications, saying that post requests must be revalidated always. I think that Apple skipped this rule in a try to save more battery and 3G traffic than their competitors, but it's a really very bad idea. The good thing is that I've learned to apply global filters to any action in a MVC project.