Updating cached CSS files in ASP.NET MVC 3 using dotLess

I had an issue with caching in an ASP.NET MVC3 web site that I was working on recently where users weren’t getting updates to CSS and image files. CSS is rather easy to resolve using the well-known query string hack, but doing the same for images referenced from within the CSS files is a bit trickier. Luckily the solution becomes trivial with a little help from dotLess.

The web application in question used one CSS file which pulled in all the images used for the layout. So there were no <img> tags anywhere in the HTML, which made the task easier. Here’s the relevant code from _Layout.chtml:

The application also had a version number that was automatically generated after each check-in to source control, which was used to version the application’s assemblies and for other bookkeeping tasks. Since I already had that bit of information handy, I created an extension method named AppVersion that returned the version number as a string and used that for the query string hack:

Which expands to the following at runtime:

Since the application version changes with each commit to source control, clients will redownload the CSS file with each new deployment, which is exactly what I needed.

Now the same needs to be done for any images used in the CSS file. Consider the following CSS snippet:

To apply the caching hack to the images, a query string needs to be appended to the end of the URLs:

Here is where it gets interesting: If a LESS file is followed by a query string in a link tag, then dotLess will insert every key-value pair in the query string as a variable in the LESS file. So when dotLess sees the following in the HTML code:

It will interpret Site.less as if a variable named @version is inserted at the begining of the file, as follows:

With that in mind, it’s possible to add the version number to the image URLs using string interpolation:

Which at runtime transforms to the following:

So now the query string hack is applied to image files as well, and clients will redownload both CSS file and images referenced in the CSS files with every new deployment.

Neat, ain’t it?

I stumbled upon this feature by accident, and I actually thought it was a bug in dotLess since I saw no mention of it in the documentation. Only after looking at the code was I able to figure out what was really going on. I wonder what other undocumented goodies dotLess might be hiding.

Leave a Reply