Adventures in HttpContext All the stuff after 'Hello, World'

Prevent Js and Css Browser Caching Issues with ASP.NET

You’ve seen this problem before- you deploy a new version of your website but the style is off and you’re getting weird javascript errors. You know the issue: Firefox or IE is caching and old version of the css/js file and it’s screwing up the web app. The user needs to clear the cache so the latest version is pulled. The solution: versionstamp your include files!

Take a lesson from Rails and create a helper which appends a stamp to your include files (and takes care of the other required markup). It’s simple- embed the following code in your views:

<%=SiteHelper.JsUrl("global.js") %>

will render

<script type="text/javascript" src="http://blog.michaelhamrah.com/content/js/global.js?33433651"></script>

The browser will invalidate the cache because of the new query string and you’ll be problem free. Version stamps are better than timestamps because the version will only change if you redeploy your site.

Here’s the code, which is based on the AppHelper for Rob Conery’s Storefront MVC:

using System.Reflection;
using System.Web.Mvc;

namespace ViewSample
{
public static class SiteHelper
{
private static readonly string _assemblyRevision = Assembly.GetExecutingAssembly().GetName().Version.Build.ToString() + Assembly.GetExecutingAssembly().GetName().Version.Revision.ToString();

/// <summary>
/// Returns an absolute reference to the Content directory
/// </summary>
public static string ContentRoot
{
get
{
return "/content";
}
}

/// <summary>
/// Builds a CSS URL with a versionstamp
/// </summary>
/// <param name="cssFile">The name of the CSS file</param>
public static string CssUrl(string cssFile)
{

string result = string.Format("<link rel='Stylesheet' type='text/css' href='{0}/css/{1}?{2}' />", ContentRoot, cssFile, _assemblyRevision);
return result;
}
/// <summary>
/// Builds a js URL with a versionstamp
/// </summary>
/// <param name="cssFile">The name of the CSS file</param>
public static string JsUrl(string jsPath)
{
return string.Format("<script type='text/javascript' src='{0}/js/{1}?{2}'></script>", ContentRoot, jsPath, _assemblyRevision);
}

}
}