ASP.NET Optimization - Bundling

Pelle picture Pelle · Mar 1, 2012 · Viewed 12.9k times · Source

I've been trying out the new minification and bundling feature in ASP.NET MVC 4, and it works great as long as you use the default folder conventions for css and js files.

/Content
/Scripts

I usually put css and script in a folder called Static like this

/Static/Css
/Static/Js

I tried to register my own bundles like this:

public static class BundleCollectionExtensions
{
    public static void RegisterScriptsAndCss(this BundleCollection bundles)
    {
        var bootstrapCss = new Bundle("~/Static/Css", new CssMinify());
        bootstrapCss.AddDirectory("~/Static/Css", "*.css");
        bootstrapCss.AddFile("~/Static/Css/MvcValidation.css");
        bootstrapCss.AddFile("~/Static/Css/bootstrap-responsive.min.css");
        bootstrapCss.AddFile("~/Static/Css/bootstrap.min.css");

        bundles.Add(bootstrapCss);

        var bootstrapJs = new Bundle("~/Static/Js", new JsMinify());
        bootstrapJs.AddDirectory("~/Static/Js", "*.js");
        bootstrapJs.AddFile("~/Static/Js/jquery-1.7.1.min.js");
        bootstrapJs.AddFile("~/Static/Js/jquery.validate.min.js");
        bootstrapJs.AddFile("~/Static/Js/jquery.validate.unobtrusive.min.js");
        bootstrapJs.AddFile("~/Static/Js/bootstrap.min.js");
        bootstrapJs.AddFile("~/Static/Js/gunsforhire.js");

        bundles.Add(bootstrapJs);
    }
}

And in

Global.ascx.cs

I did this:

BundleTable.Bundles.RegisterScriptsAndCss();

The generated markup looks like this:

<link href="/Static/Css?v=D9JdmLZFFwjRwraNKfA1uei_YMoBoqLf-gFc0zHivM41" rel="stylesheet" type="text/css" />

<script src="/Static/Js?v=mbKbf5__802kj-2LS5j9Ba-wvSxBCKNMQGBgzou6iZs1" type="text/javascript"></script>

However It's doesn't work, the request looks like this:

Request URL:http://localhost:49603/Static/Js?v=mbKbf5__802kj-2LS5j9Ba-wvSxBCKNMQGBgzou6iZs1
Request Method:GET
Status Code:301 Moved Permanently (from cache)
Query String Parametersview URL encoded
v:mbKbf5__802kj-2LS5j9Ba-wvSxBCKNMQGBgzou6iZs1

Request URL:http://localhost:49603/Static/Js/?v=mbKbf5__802kj-2LS5j9Ba-wvSxBCKNMQGBgzou6iZs1
Request Method:GET
Status Code:404 Not Found
Request Headersview source
Accept:*/*
Accept-Charset:ISO-8859-1,utf-8;q=0.7,*;q=0.3
Accept-Encoding:gzip,deflate,sdch
Accept-Language:en-US,en;q=0.8
Connection:keep-alive
Host:localhost:49603
Referer:http://localhost:49603/
User-Agent:Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/535.11 (KHTML, like Gecko)        Chrome/17.0.963.56 Safari/535.11
Query String Parametersview URL encoded
v:mbKbf5__802kj-2LS5j9Ba-wvSxBCKNMQGBgzou6iZs1
Response Headersview source
Cache-Control:private
Content-Length:4757
Content-Type:text/html; charset=utf-8
Date:Thu, 01 Mar 2012 19:05:44 GMT
Server:Microsoft-IIS/7.5
X-Powered-By:ASP.NET
X-SourceFiles:=?UTF-8?B?   QzpcQENvZGVccGVsbGVccGVsbGVoZW5yaWtzc29uLnNlXHNyY1xXZWJcU3RhdGljXEpzXA==?=

What am I doing wrong?

Update

I think I was finally able to solve this by doing the following:

  1. Removing the AddDirectory calls bootstrapCss.AddDirectory("~/Static/Css", "*.css");

  2. Giving the bundles paths that do not reflect the real directory structure

Answer

Robb Vandaveer picture Robb Vandaveer · Feb 14, 2013

What you are doing "wrong" is that your bundle path corresponds to a REAL path. As I understand it, when the request for "/Static/Css?v=D9JdmLZFFwjRwraNKfA1uei_YMoBoqLf-gFc0zHivM41" comes in, the routing engine first looks for a physical path. It finds a match with your folder "static" and it tries to find a file in it that matches "Css?v=D9JdmLZFFwjRwraNKfA1uei_YMoBoqLf-gFc0zHivM41". When it can't find one, because it doesn't exist, it gives a 404. (I've also seen an access denied.) When the routing engine can't find a physical file path it then looks to other handlers like bundling and minification to serve up the request.

Anyway I think you've figured it out from your comments but I'm not sure it will be very clear to anyone that finds your question. Simply change your registration from:

var bootstrapCss = new Bundle("~/Static/Css", new CssMinify());

to:

var bootstrapCss = new Bundle("~/bundles/Css", new CssMinify());

If you make that change, your issue will go away, (granted there is no physical path that corresponds to "bundles".