Thursday, November 10, 2011

How to add offline functionality to your web pages using ASP.net MVC

I was recently tasked with creating an iPad client for our online survey product Prospero . My initial thoughts were that I was going to have to buy a Mac and a book on iPad programming, however after a bit of thought I realised that I could potentially use HTML5 and a combination of its offline caching and local storage capabilities.

The first issue that needs to be covered is geting the web browser to cache a version of a web page and all its required resources (images, scripts, etc) locally. Web browsers do this a lot of the time anyway in order to optimise performance, however in order for them to be used in an offline storage scenario they need to be stored in a separate cache. The way that you do this is by adding a manifest file to the page, this is done by adding a manifest attribute to the html tag.as follows:

<html manifest="/manifest.mf">


I choose to use an ashx (or web handler) to provide the manifest file so my code actually looks like the following:

<html manifest="/manifest.ashx"> 
 

  
The reason that I use a web handler is that you don't you need to make configuration changes to IIS in order to allow the manifest file extension to be associated with the correct content type. I like to keep IIS customisation to an absolute mimimum as it's just one more thing that can go wrong when deploying an app. The code for the web handler looks as follows:

using System;
using System.Web;
 
namespace Prospero
{
    public class Manifest : IHttpHandler
    {
        public void ProcessRequest(HttpContext context)
        {
            context.Response.ContentType = "text/cache-manifest";
            context.Response.WriteFile(context.Server.MapPath("~/content/survey.mf"));
        }
 
        public bool IsReusable
        {
            get
            {
                return false;
            }
        }
    }
}
 
 

In this example I have a manifest file survey,mdf in the content directory of my application.

The next rather daunting task is to work out what exactly needs to be written in the out in the manifest file. I realised that this should be pretty easy to work out by opening the web page and checking what resources had been downloaded using Firebug . I then wondered if someone has written a tool to automate this process and a quick Google turned up Manifested  . This awesome little tool will analyse your web page and tell you exactly what should be in your manifest file - just cut and paste the results into your .mf file!

Now you're all set to go - all you need to do is browse to your web page and it will be cached locally. If you  use Firefox to develop in you will get a warning bar at the top of the page asking you for permission to cache data locally - say yes and you're done. Now if you re-visit the page you will not be making any internet call except a call to retrieve the manifest file (if you are still online), this is done to check if there is a newer version on the server.  The way the browser determins if the file is newer is by checking the revision number in the file - you can force the browser to download all newer versions of your cached files by incrementing the revision number.


If you would like to double check what Firefox has cached you can do so by typing about:cache in the browser URL bar, the Offline Cache Device section show what is stored.

1 comment:

  1. Fantastic tip! Thank you, was jsut about to embark on an iPhone app and had the same initial thoughts, but thanks to your post I have seen another path!

    ReplyDelete