Offline Web Applications
The HTML 5 specification, now available in most evergreen web browsers, gave the power of offline web applications. How this works is a manifest file is downloaded to the client which lists all files needed to make that page useable even if there is no network connection. This manifest file can include JavaScript, CSS and HTML files. Of course, it is possible to create an ASP.NET MVC application that can use this same technique as it renders HTML 5 anyway, however there are a few gotchas to look out for which I will cover in this post.
Firstly, the path to the .manifest file needs to be included in the HTML element at the top of the page.
<html lang="en" manifest="offline.manifest">
Manifest File
CACHE MANIFEST
/
/style.css
/Scripts/main-script.js
FALLBACK:
/ /offline.html
NETWORK:
*
For an MVC site, simply add the reference to the manifest in the _Layout file and add each resource you want in the browser application cache.
CACHE MANIFEST
/
/Content/bootstrap.css
/Content/site.css
/Scripts/modernizr-2.6.2.js
/Scripts/jquery-1.10.2.js
/Scripts/bootstrap.js
/Scripts/respond.js
FALLBACK:
/offline.html
NETWORK:
*
These resources above are used for the standard MVC template you get with Visual Studio 2015.
Now to get IIS to serve up this offline.manifest file, you either have to add a mime type on the server or add it to the <system.webserver>
element in web.config.
<system.webServer>
<staticContent>
<clear/>
<mimeMap fileExtension=".css" mimeType="text/css"/>
<mimeMap fileExtension=".js" mimeType="text/javascript"/>
<mimeMap fileExtension=".manifest" mimeType="text/cache-manifest" />
<mimeMap fileExtension=".html" mimeType="text/html" />
<mimeMap fileExtension=".jpg" mimeType="image/jpeg" />
</staticContent>
<modules>
<remove name="FormsAuthentication" />
<remove name="ApplicationInsightsWebTracking" />
<add name="ApplicationInsightsWebTracking"
type="Microsoft.ApplicationInsights.Web.ApplicationInsightsHttpModule,
Microsoft.AI.Web" preCondition="managedHandler" />
</modules>
<validation validateIntegratedModeConfiguration="false" />
</system.webServer>
It's important that you add the clear
element and you need then to add the usual types your site will serve up, otherwise you will get an HTTP 500 on each of these.
In Chrome, when browsing to this page, you can examine the Application Cache by going to the developer tools (F12) and going to the Resources tab.

Make sure that the ‘Disable cache’ check box is cleared as by default it is checked when you open up the developer tools and the browser will not retrieve the files needed from the cache.

Now, by switching off your network connection or setting the Network throttling drop down to Offline (I disable my network card temporarily for a full test), your website should still view correctly and as the JavaScript has also been cached, it should function the same as well.

The main issue with the .manifest file is the browser does not know when the contents listed in it have changed unless the time stamp on the manifest itself has changed. One way to do this is to version the file and an even better way is to version it by using your application build number.
There are many issues with MVC serving up a .manifest file and the easiest solution I have found is to write out a physical file to the location the site is hosted in like this:
string path = ControllerContext.HttpContext.Server.MapPath("~/Manifest/offline.manifest");
if (System.IO.File.Exists(path))
{
System.IO.File.Delete(path);
}
var version = typeof(MvcApplication).Assembly.GetName().Version;
var manifest = "CACHE MANIFEST" + Environment.NewLine +
"# Server Assembly Version: " + version.Major + "." +
version.Minor + "." + version.Build + Environment.NewLine +
"CACHE:" + Environment.NewLine +
Url.Action("Index", "Home") + Environment.NewLine +
Url.Content("/Content/bootstrap.css") + Environment.NewLine +
Url.Content("/Content/site.css") + Environment.NewLine +
Url.Content("/Scripts/modernizr-2.6.2.js") + Environment.NewLine +
Url.Content("/Scripts/jquery-1.10.2.js") + Environment.NewLine +
Url.Content("/Scripts/bootstrap.js") + Environment.NewLine +
Url.Content("/Scripts/respond.js") + Environment.NewLine +
"NETWORK:" + Environment.NewLine +
"*" + Environment.NewLine;
using (StreamWriter sw = new StreamWriter(path))
{
sw.Write(manifest);
}
Which can be placed inside the Home/Index controller. Then add the path to the _Layout file like this:
<html lang="en" manifest="/Manifest/offline.manifest">
You will need to add write permissions to this directory for the IIS account so it can delete and write the file. Now if your build number increments each time you do a build and deploy, the manifest file will be regenerated and the client browser will pick up any changes.
Happy coding!
Related Posts
The post Offline Web Applications With MVC appeared first on Don't Believe The Type.