Adding Bundling to existing ASP.NET Web Forms

Adding bundles to an existing web forms project is fairly trivial but it is a nice feature to have. Not only does it enable some extra optimization on content delivery but it also solves issues with cached CSS files not being updated on clients browsers.

First add the nuget package

PM> Install-Package Microsoft.AspNet.Web.Optimization

Add a new static class to your web forms project the class name is not really important but for the sake of convention call it BundleConfig. Depending on the project structure it can also be placed in an App_Start folder, but it can be placed anywhere so long as the Global.asax.cs can access it.

This class is where all the bundle registrations will happen at start up, a simple example would beĀ 

public class BundleConfig {
    // For more information on bundling, visit http://go.microsoft.com/fwlink/?LinkId=301862 
    public static void RegisterBundles(BundleCollection bundles)
    {
        bundles.Add(new ScriptBundle("~/bundles/js")
        .Include("~/Scripts/jquery-{version}.js")
        .Transforms.Add(new JsMinify()));

        bundles.Add(new StyleBundle("~/bundles/css")
        .Include("~/Content/site.css")
        .Transforms.Add(new CssMinify())); 
    } 
}

Includes can be chained to add as many files to the bundle as required. The transforms will automatically minify the files when bundling but can cause issues with some scripts so may need to be disabled. Stylesheets may also need to be updated if they include any relative references to images; since the bundling uses a virtual path all references must be absolute.

In the Global.asax.cs add the Application_Start overload if it is not already present and call the RegisterBundles method. Also remember the using references

protected void Application_Start(object sender, EventArgs e) 
{
    BundleTable.EnableOptimizations = true;
    BundleConfig.RegisterBundles(BundlesTable.Bundles);
}

By default bundling will only be enabled when debug is set to false in the web.config, int that case the CSS and JS link tags will be output as normal, i.e no bundling. The EnableOptimizations flag on the BundleTable allows this to be overridden.

To spit the bundles out on the page a placeholder server control is usually best, and then directly output using server tags.

<asp:PlaceHolder runat="server">
    <%: Styles.Render("~/bundles/css") %>
</asp:PlaceHolder>

<asp:PlaceHolder runat="server">
    <%: Scripts.Render("~/bundles/js") %>
</asp:PlaceHolder>

Now running the site all the css will be combined and minified on application start and also have a version guid appended like so:

<link href="/bundles/css?v=Dn8140cLCV8xEOGELRbm2ZN1S5Zoj8iSfG8yo5Ht7CE1" rel="stylesheet" />

Any updates to the css or bundles configuration means any browsers that have previously visited the site should update their cache.