This blog post is a guest post from Maxime Rouiller. If you want to make blog post about Web technology, please contact me at firstname.lastname@example.org.
Maxime Rouiller is a passionate .NET technology specialist and ASP.NET MVP, working for 8 years in large software development, advocating Agile and TDD. Aware of the latest technological trends, he intervenes as a specialist in the .NET Montreal usergroup and acts regularly as a speaker for Web Form programmers on the MVC platform.
So I’ve been wanting to write about this since the build and only gotten around to do it now.
This caused problems as we had to alter our Development version of our HTML to fit our Production environment. Microsoft released this tid bit early because it’s probably going to be integrated in the .NET 4.5 framework but is making it available to us now.
Please be aware that “Microsoft.*” DLLs are not part of the official framework and when they do, they will probably be changed namespace to “System.*”.
First, you will need NuGet to install the following packages:
Now, the way the JS/CSS minifying works is that it will dynamically inspect all your files, read them, minify them and then cache the result to be served later. This allows us to modify our files and have all the files re-minified. When one of our JS/CSS files get modified again, this process will restart until either the cache expires or a file change.
For the minify-er to work, it will require the registration of a HttpModule. It’s not already included in the Microsoft.Web.Optimization package, but it will be necessary for us to add it if we want it to work.
[assembly: WebActivator.PreApplicationStartMethod(typeof(MvcBackbonePrototype.AppStart.BundleAppStart), "Start")]
public static class BundleAppStart
public static void Start()
private static void RegisterFolders()
// configure Microsoft.Web.Optimization
The previous code will do the following, when your application start, it will register a dynamic HttpModule.
Now that the base work is done, we’ll jump right ahead to the configuration of the folders.
Now that the HttpModule is properly registered, we need to tell the Module when to activate itself. In my specific scenario, I wanted to have jQuery, underscore.js and Backbone.js in that specific order.
By default, the Module will load most core frameworks first (jQuery, MooTools, prototype, scriptaculous) and then load the rest of the files that doesn’t match the wildcards after. The filters are done so that jQuery plugins will load after the jQuery core library, and jQuery UI will load after jQuery.
However, there is nothing done for underscore.js and Backbone.js.
private static void RegisterFolders()
var js = new DynamicFolderBundle("js", typeof(JsMinify), "*.js", false);
The previous code correctly configures the module to minify all files in a folder by just adding the suffix “js” to the folder (eg.: /Scripts/js).
However, it will register the other modules in alphabetical order rather than the proper order.
Let’s fix that.
public class BackboneOrderer : DefaultBundleOrderer
public override IEnumerable<FileInfo> OrderFiles(BundleContext context, IEnumerable<FileInfo> files)
var backboneOrdering = new BundleFileSetOrdering("backbone");
return base.OrderFiles(context, files);
We first inherit from the default order. Then, we add the default file ordering, which will take care of the jQuery ordering for us. Then, we add the other files that we require to the list. The only thing left is to alter our RegisterFolders method to fix that.
js.Orderer = new BackboneOrderer();
That’s it. We are nearly done!
Modifying your _Layout.cshtml / masterpage
My masterpage head section first looked a lot like this:
This was of course replaced by the following:
And that’s all! All your files will be minimized, bundled and properly cached.
If you want to have your URLs with a “version number” on it, I suggest that you use the following methods to resolve your URLs instead of the MVC way:
<script src="@Microsoft.Web.Optimization.BundleTable.Bundles.ResolveBundleUrl("~/Scripts/Framework/js", true)"></script>