Tom Hall Tom Hall - 1 month ago 12
CSS Question

MVC4 StyleBundle not resolving images

My question is similar to this:


ASP.NET MVC 4 Minification & Background Images


Except that I want to stick with MVC's own bundling if I can. I'm having a brain crash trying to figure out what the correct pattern is for specifying style bundles such that standalone css and image sets such as jQuery UI work.

I have a typical MVC site structure with
/Content/css/
which contains my base CSS such as
styles.css
. Within that css folder I also have subfolders such as
/jquery-ui
which contains its CSS file plus an
/images
folder. Image paths in the jQuery UI CSS are relative to that folder and I don't want to mess with them.

As I understand it, when I specify a
StyleBundle
I need to specify a virtual path which does not also match a real content path, because (assuming I'm ignoring routes to Content) IIS would then try to resolve that path as a physical file. So I'm specifying:

bundles.Add(new StyleBundle("~/Content/styles/jquery-ui")
.Include("~/Content/css/jquery-ui/*.css"));


rendered using:

@Styles.Render("~/Content/styles/jquery-ui")


I can see the request going out to:

http://localhost/MySite/Content/styles/jquery-ui?v=nL_6HPFtzoqrts9nwrtjq0VQFYnhMjY5EopXsK8cxmg1


This is returning the correct, minified CSS response.
But then the browser sends a request for a relatively linked image as:

http://localhost/MySite/Content/styles/images/ui-bg_highlight-soft_100_eeeeee_1x100.png


Which is a
404
.

I understand that the last part of my URL
jquery-ui
is an extensionless URL, a handler for my bundle, so I can see why the relative request for the image is simply
/styles/images/
.

So my question is what is the correct way of handling this situation?

Answer

According to this thread on MVC4 css bundling and image references, if you define your bundle as:

bundles.Add(new StyleBundle("~/Content/css/jquery-ui/bundle")
                   .Include("~/Content/css/jquery-ui/*.css"));

Where you define the bundle on the same path as the source files that made up the bundle, the relative image paths will still work. The last part of the bundle path is really the file name for that specific bundle (i.e., /bundle can be any name you like).

This will only work if you are bundling together CSS from the same folder (which I think makes sense from a bundling perspective).

Update

As per the comment below by @Hao Kung, alternatively this may now be achieved by applying a CssRewriteUrlTransformation (Change relative URL references to CSS files when bundled).

NOTE: I have not confirmed comments regarding issues with rewriting to absolute paths within a virtual directory, so this may not work for everyone (?).

bundles.Add(new StyleBundle("~/Content/css/jquery-ui/bundle")
                   .Include("~/Content/css/jquery-ui/*.css",
                    new CssRewriteUrlTransform()));