Anyone that tried to cache static files eventually got to a point where cache caused more problems than it solved. After all, telling all your users to press Ctrl + Refresh in their browsers is not exactly how one should do things on the web. Two years ago Mads Kristensen presented us with a solution in his article Cache busting in ASP.NET. The solution uses Fingerprint class, that basically updates cache object every time a static file is changed.

All fine and well. So why do I jab about it now? The solution, in my opinion has two glitches:

1. It is tightly bound with URL Rewrite IIS module.

2. It always links static content to root URL.

So, without further ado, I present you with “upgraded” solution that avoids both issues and works with relative URLs (relative to application URL anyway). In-page usage remains the same.

using System.IO;
using System.Web;
using System.Web.Caching;
using System.Web.Hosting;

public static class Fingerprint
{

	public static string Tag(string rootRelativePath)
	{
		if (null == HttpRuntime.Cache[rootRelativePath])
		{
			var absolute = HostingEnvironment.MapPath("~" + rootRelativePath);
			var dateLastWrite = File.GetLastWriteTime(absolute);
			var result = VirtualPathUtility.ToAbsolute(
				string.Format("~{0}?{1}", 
					rootRelativePath, 
					dateLastWrite.Ticks));
			HttpRuntime.Cache.Insert(
				rootRelativePath, 
				result, 
				new CacheDependency(absolute));
		}
		return HttpRuntime.Cache[rootRelativePath] as string;
	}

}

This code is also available as gist.