45

MVC's bundling is returning the wrong URL in CSS images when using CssRewriteUrlTransform:

I have an intranet application whose URL is, for example: http://usid01-srv002/MyApplication. It's in IIS's "Default Web Site".

Which has the following in BundleConfig.cs:

bundles.Add(new StyleBundle("~/bundles/jcss")
    .Include("~/Scripts/JQueryUI/css/*.css", new CssRewriteUrlTransform())
);

The bundling system is generating the wrong URL for any images referenced in those CSS files, yielding 404's even JQueryUI's very well tested CSS files (from FireBug):

404 errors due to wrong generated URL

e.g. it's generating

http://usid01/path/foo.png

When it should be generating:

http://usid01/MyApplication/path/foo.png

How do I get the bundling system to generate a URL that points to the right location?

Charles Burns
  • 9,631
  • 7
  • 58
  • 77
  • How did you define your CssRewriteUrlTransform class? – Lin Dec 10 '13 at 03:03
  • 1
    @lin: I didn't. As far as I can tell, it doesn't have a lot of options: http://msdn.microsoft.com/en-us/library/system.web.optimization.cssrewriteurltransform.process(v=vs.110).aspx – Charles Burns Dec 10 '13 at 15:53
  • 1
    You are right, it doesn't have a lot of options. but if these options are not set up correctly, you can't get the absolute paths. This link may help you. http://aspnetoptimization.codeplex.com/workitem/83 – Lin Dec 10 '13 at 17:50
  • 3
    What I am getting from this: Don't use bundling on CSS with paths because it is broken except in very simple cases. It's much easier to just directly link minified CSS. – Charles Burns Dec 12 '13 at 21:07
  • possible duplicate of [MVC4 StyleBundle not resolving images](http://stackoverflow.com/questions/11355935/mvc4-stylebundle-not-resolving-images) – Amirhossein Mehrvarzi Sep 21 '14 at 00:47
  • SEE ALSO: Answer below by `Muhammad Waqas Iqbal` ... SEE ALSO: https://stackoverflow.com/questions/11355935/mvc4-stylebundle-not-resolving-images – Jonathan Jun 04 '17 at 12:54

3 Answers3

52

CssRewriteUrlTransform updates the CSS Url with absolute path, saying so if we use -

bundles.Add(new StyleBundle("~/Content/css").Include("~/Content/site.css",new CssRewriteUrlTransform()));

and we have following CSS class in "site.css"

.Sandy
{
    background-image: url("Images/Sandy.jpg");
    border: 1px solid #c8c8c8;
    border-radius:4px 4px 4px 4px;
    box-shadow: 1px 1px 8px gray;
    background-position:left;
    background-size:contain;
    -moz-background-size:contain;
    -webkit-background-size:contain;
    -o-background-size:contain;
    background-repeat:no-repeat;
    min-height:100px;
    min-width:100px;
    display:block;
}

and following folder structure -

   -Web site Root
   -Content
   --site.css
   --Images
   ---Sandy.jpg

Bundling will generate following CSS Url Path for "background-image" -

 background-image: url("/Content/Images/Sandy.jpg");

And now if you hosting the website / web application as a website on web server above path will work, because browser will send request for this resource using following Url because of leading '/'

http://<server>/content/images/sandy.jpg

but if you host the website as web application this will create problem. Because browser will still interpret this as absolute Url instead of relative and still send following request to fetch this resource -

   http://<server>/content/images/sandy.jpg

So, the solution for this problem is using the relative Url even in CSS file and then remove the CssRewriteUrlTransform from the Bundle config as below -

background-image: url("Images/Sandy.jpg");

bundles.Add(new StyleBundle("~/Content/css").Include("~/Content/site.css"));
Bhalchandra K
  • 2,511
  • 3
  • 24
  • 38
  • Without changing the `CSS` [here](http://stackoverflow.com/a/19765418/2218697) is **another extension method** which may help someone. – Shaiju T Apr 16 '17 at 11:54
8

The reason for the broken images is that it tries to find the images relative to the new path defined during bundling i.e.

bundles.Add(new StyleBundle("~/Content/woothemes").Include(
            "~/Content/woothemes/css/style.css",
));

So if there is any image path (i.e. background image) defined in style.css, it will try to get its path relative to Content/woothemes instead of Content/woothemes/css/, hence the images will not be found

One workaround to overcome the issue for the files of same folder is to define the new path same as that of the folder (whose files are being minified) i.e.

bundles.Add(new StyleBundle("~/Content/woothemes/css").Include(
            "~/Content/woothemes/css/style.css",
));

This way the bundled files and the actual files path will match and the images defined in the css will be found, hence the issue will be resolved

The issue will only not be resolved if you mix the files from different folders for the same reason described above

Muhammad Waqas Iqbal
  • 3,014
  • 1
  • 16
  • 9
  • 5
    Your answer is in my opinion the most important. If you're going to use a style bundle it's important to understand that your css relative urls will be relative to the bundle, and the last token on the bundle url is similar to a file, not a directory, so in the above example "~/Content/woothemes" could be thought of as "~/Content/woothemes.css", meaning your urls are relative to ~/Content/ – Jonathan Jun 04 '17 at 12:41
4

This works for me,

<link href="@System.Web.Optimization.BundleTable.Bundles.ResolveBundleUrl("~/content/styles/css")" rel="stylesheet" type="text/css" />