I've got an MVC application and I'm using the StyleBundle
class for rendering out CSS files like this:
bundles.Add(new StyleBundle("~/bundles/css").Include("~/Content/*.css"));
The problem I have is that in Debug
mode, the CSS urls are rendered out individually, and I have a web proxy that aggressively caches these urls. In Release
mode, I know a query string is added to the final url to invalidate any caches for each release.
Is it possible to configure StyleBundle
to add a random querystring in Debug
mode as well to produce the following output to get around the caching issue?
<link href="/stylesheet.css?random=some_random_string" rel="stylesheet"/>
You can create a custom IBundleTransform class to do this. Here's an example that will append a v=[filehash] parameter using a hash of the file contents.
You can then register the class by adding it to the Transforms collection of your bundles.
Now the version number will only change if the file contents change.
You just need a unique string. It doesn't have to be Hash. We use the LastModified date of the file and get the Ticks from there. Opening and reading the file is expensive as @Todd noted. Ticks is enough to output a unique number that changes when the file is changed.
and how to use it:
and this is what MVC writes:
works fine with Script bundles too.
This library can add the cache-busting hash to your bundle files in debug mode, as well as a few other cache-busting things: https://github.com/kemmis/System.Web.Optimization.HashCache
You can apply HashCache to all bundles in a BundlesCollection
Execute the ApplyHashCache() extension method on the BundlesCollection Instance after all bundles have been added to the collection.
Or you can apply HashCache to a single Bundle
Create an instance of the HashCacheTransform and add it to the bundle instance you want to apply HashCache to.
I've had the same problem but with cached versions in client browsers after an upgrade. My solution is to wrap the call to
@Styles.Render("~/Content/css")
in my own renderer that appends our version number in the query string like this:And then in the view I do like this:
Note this is written for Scripts but also works for Styles (just change those key words)
Building on @Johan's answer:
Usage:
Replacing
Benefits:
Also, when you need to quickly workaround Bundler:
Usage:
Replacing:
(Also replaces many other alternative lookups)
Not currently but this is slated to be added soon (right now scheduled for the 1.1 stable release, you can track this issue here: Codeplex