ARROYOCODE

Asset and Bundling Management in ASP.NET MVC 3

Introduction

user

ARROYOCODE

A former IT/IS manager turned developer, husband, and co-creator of three whom have yet to use a WYSIWYG.

mvc, asp.net, bundling, asset, management, cassette

Asset and Bundling Management in ASP.NET MVC 3

Posted by Greg Arroyo on .
Featured

mvc, asp.net, bundling, asset, management, cassette

Asset and Bundling Management in ASP.NET MVC 3

Posted by Greg Arroyo on .

Cassette, created by Andrew Davey (@getcassette) is an asset bundling and management utility for ASP.NET WebForms and MVC web apps. Typically, a developer places application assets (javascript, CoffeeScript, CSS, LESS, HTML templates and so on) in a folder with appropriate references in code/html. For most, asset management stops here. If the developer is concerned with application performance, additional measures are typically created for handling browser cache-busting and minification of content, maybe a BasePage class, Application_Start() and so on.

With Cassette, asset bundling for use within .NET web application development is a welcome, free, open source alternative that automatically sorts, concatenates, minifies (production mode), caches and versions all application Javascript, CoffeeScript, CSS, LESS and HTML templates at HTTP request time! Furthermore, it provides the freedom to use non *.min.js script content in DEBUG mode for development flexibility with automatic minification, etc. in production environments(web.config or provided configuration .cs file) that are comparable to original *.min.js files.

Today we'll build a sample MVC application using Cassette. Read on!

Getting Started

Cassette is available via Nuget or alternatively forked via GitHub repository. For post brevity, we've already created an empty MVC application with appropriate default view using Razor syntax (aspx, spark will also work). For this example, we'll be using the Nuget Package Manager to add Cassette to our sample MVC3 application (WebForms documentation can be found here).

PM> Install-Package Cassette.Web

The Package Manager adds the following referenced dependencies to the application:

AjaxMin
Cassette
Cassette.Views
Cassette.Web
Jurassic
Microsoft.Web.Infrastructure
Newtonsoft.Json
WebActivator

A CassetteConfiguration.cs file is added to project containing class information for configuring Cassette and finally, the Package Manager updates the ~\Views\Web.config file adding the Cassette.Views namespace to provide access to the Cassette Bundles helper class. Please note: If you are using MVC Areas, you will need to edit the Web.config for each area similarly.

<configuration>
    ...
    <system.web.webPages.razor>
        <pages>
            <namespaces>
                ...
                <add namespace="Cassette.Views"/>
            </namespaces>
        </pages>
    </system.web.webPages.razor>
    ...
</configuration>

Assets, Bundles & Configuration

Before we get to much further, it's important to understand the difference between Assets and Bundles when integrating Cassette. An asset is any source file used by a browser (i.e.: Javascript, stylesheets, HTML Templates). A bundle is a group or collection of assets that make up a single logical source. Cassette allows you to keep each asset separate for ease-of-use when debugging and will concatenate files together and compress them in production mode when enabled.

Bundles can be added to the BundleCollection using an Add method with a generic type parameter to specify the type of bundle being added. Here we've updated the CassetteConfiguration.cs file to have Cassette bundle CSS files from the ~/Content directory and Javascript files from the ~/Scripts directory using the default mechanism of one bundle per file basis. With our configuration complete, it's now time to integrate Cassette into the sample application.

public class CassetteConfiguration : ICassetteConfiguration
{
    public void Configure(BundleCollection bundles, CassetteSettings settings)
    {
        // Using default configuration; Each file bundled separately
        // Please read http://getcassette.net/documentation/configuration
        bundles.AddPerIndividualFile<StylesheetBundle>("Content");
        bundles.AddPerIndividualFile<ScriptBundle>("Scripts");
    }
}

Cassette is truly a flexible in that it supports either one bundle per asset, all assets within a directory in a single bundle and/or bundling by individual directories. The choice is up to the developer.

Using Cassette in the Sample Application

In this example, we simply define bundle references at the top of our Views/Home/Index.cshtml view for default global application use. Optionally, we have elected to provide Cassette with pageLocation values to target specific render locations within our view (i.e.: place certain Javascript assets in head and/or footer). Next, we add appropriate inline expressions in our Views/Shared/_Layout.cshtml shared view responsible for rendering out bundle content at run time.

@{
    Bundles.Reference("Content/Site.css");
    Bundles.Reference("Scripts/modernizr-2.0.6-development-only.js", "headerScripts");
    Bundles.Reference("Scripts/jquery-1.7.1.js", "footerScripts");
}

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title>Cassette Sample</title>
    @Bundles.RenderStylesheets()
    @Bundles.RenderScripts("headerScripts")
</head>
<body>
    @RenderBody()
    @Bundles.RenderScripts("footerScripts")
</body>
</html>

That's it! Referenced assets are bundled and placed where directed. A quick Source View shows the following output complete with automatic asset versioning in place (versioning IDs shortened for readability).

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title>Cassette Sample</title>
    <link href="/_cassette/asset/Content/Site.css?2c01bfe" type="text/css" rel="stylesheet"/>
    <script src="/_cassette/asset/Scripts/modernizr-2.0.6-development-only.js?a123fe" type="text/javascript"></script>
</head>
<body>

<h2>Cassette.Sample Solution</h2>
<p>Cassette, an open source project, provides truly "developer-friendly" asset bundling and management that automatically sorts, concatenates, minifies, caches and versions all your Javascript, CoffeeScript, CSS, LESS and HTML template content within your ASP.NET MVC or WebForms application.</p>
<p>Learn more, visit <a href="/Home/http%3a/getcassette.net">getcassette.net</a></p>

<script src="/_cassette/asset/Scripts/jquery-1.7.1.js?b47730ff" type="text/javascript"></script>
</body>
</html>

The Beauty That Is Debug="False"

One of the strongest selling points for using Cassette is it's ability to automatically compress and minify assets saving valueable bandwidth and reduction of page size delivered to viewers, not to mention the pure performance bonus for smaller sizes. To enable the "Production Mode" feature, we simply set our application root Web.config compilation debug value from true to false (which should be done already as a best practice). As indicated previously, *.min.js files are not needed when using Cassette. Runtime compression and minification before and after examples demonstrate Cassette's ability in action.

body {
    font-size: .85em;
    font-family: "Trebuchet MS", Verdana, Helvetica, Sans-Serif;
    color: #232323;
    background-color: #fff;
}

.links {
    color: #ff0000;
    text-decoration: none;
}

body {font-size:.85em;font-family:"Trebuchet MS", Verdana, Helvetica, Sans-Serif; color:#232323;background-color:#fff}

/* Site.js
* Contains general application javascript for sizzle.
*/
$(function () {
    $("a").addClass("links").fadeIn('slow'); // Apply link CSS class and fade in
});

$(function(){$("a").addClass("links").fadeIn("slow")})

Cassette is a powerful optimization tool that provides the developer added, pain-free benefits when developing ASP.NET web applications with very little effort. Davey's time and energy in the creation of such a utility is highly appreciated. Very little configuration, tremendous upside with open source licensing is huge for anybody concerned about their website performance. This post represents a mere fraction of what Cassette is capable of. We encourage everybody to check out Cassette (http://www.getcassette.net) for themselves and maybe while they're at it, follow on twitter @getcassette.

Download Example Code from GitHub

user

Greg Arroyo

A former IT/IS manager turned developer, husband, and co-creator of three whom have yet to use a WYSIWYG.