Mvc Bundling and Relative CSS Image When Website Is Deployed to an Application

mvc bundling and relative css image when website is deployed to an application

If there are no virtual directories involved the following code would do:

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

but when VirtualDirectory is used CssRewriteUrlTransform will rewrite to Host instead of Host/VirtualDirectory. the solution is to derive CssRewriteUrlTransform which is fully discussed here: ASP.NET MVC4 Bundling with Twitter Bootstrap:

public class CssRewriteUrlTransformWrapper : IItemTransform
{
public string Process(string includedVirtualPath, string input)
{
return new CssRewriteUrlTransform().Process("~" + VirtualPathUtility.ToAbsolute(includedVirtualPath), input);
}
}

MVC Bundling and CSS relative URLs

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"));

MVC4 StyleBundle not resolving images

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()));

CSS and Javascript and images in ASP.NET MVC 5 website won't display after deployment

Try this in your bundle config

 BundleTable.EnableOptimizations = false;

ASP.NET MVC4 Bundling with Twitter Bootstrap

The issue is most likely that the icons/images in the css files are using relative paths, so if your bundle doesn't live in the same app relative path as your unbundled css files, they become broken links.

We have rebasing urls in css on our todo list, but for now, the easist thing to do is to have your bundle path look like the css directory so the relative urls just work, i.e:

new StyleBundle("~/Static/Css/bootstrap/bundle")

Update: We have added support for this in the 1.1beta1 release, so to automatically rewrite the image urls, you can add a new ItemTransform which does this rebasing automatically.

bundles.Add(new StyleBundle("~/bundles/publiccss").Include(
"~/Static/Css/bootstrap/bootstrap.css",
"~/Static/Css/bootstrap/bootstrap-padding-top.css",
"~/Static/Css/bootstrap/bootstrap-responsive.css",
"~/Static/Css/bootstrap/docs.css", new CssRewriteUrlTransform()));

CssRewriteUrlTransform with or without virtual directory

I am not sure to fully understand your problem, but seeing http://localhost here seems wrong. You should never use an absolute URL for your bundles.

For me CssRewriteUrlTransform works perfectly, here is how I use it:

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

"Bundles" is virtual.

Does this helps?

Update

I was confused with the "VirtualDir" thing, as you are talking about IIS VirtualDir, and I was thinking Bundle VirtualDir! It's true that in this case CssRewriteUrlTransform will rewrite URLs to the Host, not to the Host/VirtualDir URI.

To do that, you have to derive CssRewriteUrlTransform to make it do what you need it to.
There is a good discussion here: ASP.NET MVC4 Bundling with Twitter Bootstrap

Seems the best answer is there:http://aspnetoptimization.codeplex.com/workitem/83

public class CssRewriteUrlTransformWrapper : IItemTransform
{
public string Process(string includedVirtualPath, string input)
{
return new CssRewriteUrlTransform().Process("~" + VirtualPathUtility.ToAbsolute(includedVirtualPath), input);
}
}

Use this class instead of CssRewriteUrlTransform

Why is Windows Azure adding '/bundles/' into all of my css image file paths?

Why is Windows Azure adding '/bundles/' into all of my css image file paths?

Your CSS file is getting bundled. ASP.NET is putting your CSS file into a new file and storing it at mydomain.net/bundles/somefile.css. The web browser is looking for your image relative to the CSS files location.

This is only happening on Azure because bundling only runs in release configuration not in debug configuration. So, you can test bundling locally by setting <compilation debug="false" /> in your web.config file.

What is the best way to remove ... this problem?

Take a look at this: MVC4 StyleBundle not resolving images and this MVC cannot display image using background-url in css - uses bundling, or just do not use bundling. :)

Why is my CSS bundling not working with a bin deployed MVC4 app?

The CSS and Script bundling should work regardless if .NET is running 4.0 or 4.5. I am running .NET 4.0 and it works fine for me. However in order to get the minification and bundling behavior to work your web.config must be set to not be running in debug mode.

<compilation debug="false" targetFramework="4.0">

Take this bundle for jQuery UI example in the _Layout.cshtml file.

@Styles.Render("~/Content/themes/base/css")

If I run with debug="true" I get the following HTML.

<link href="/Content/themes/base/jquery.ui.core.css" rel="stylesheet"/>
<link href="/Content/themes/base/jquery.ui.resizable.css" rel="stylesheet"/>
<link href="/Content/themes/base/jquery.ui.selectable.css" rel="stylesheet"/>
<link href="/Content/themes/base/jquery.ui.accordion.css" rel="stylesheet"/>
<link href="/Content/themes/base/jquery.ui.autocomplete.css" rel="stylesheet"/>
<link href="/Content/themes/base/jquery.ui.button.css" rel="stylesheet"/>
<link href="/Content/themes/base/jquery.ui.dialog.css" rel="stylesheet"/>
<link href="/Content/themes/base/jquery.ui.slider.css" rel="stylesheet"/>
<link href="/Content/themes/base/jquery.ui.tabs.css" rel="stylesheet"/>
<link href="/Content/themes/base/jquery.ui.datepicker.css" rel="stylesheet"/>
<link href="/Content/themes/base/jquery.ui.progressbar.css" rel="stylesheet"/>
<link href="/Content/themes/base/jquery.ui.theme.css" rel="stylesheet"/>

But if I run with debug="false". I'll get this instead.

<link href="/Content/themes/base/css?v=myqT7npwmF2ABsuSaHqt8SCvK8UFWpRv7T4M8r3kiK01" rel="stylesheet"/>

This is a feature so you can easily debug problems with your Script and CSS files. I'm using the MVC4 RTM.

If you think it might be an MVC dependency problem, I'd recommend going into Nuget and removing all of your MVC related packages, and then search for the Microsoft.AspNet.Mvc package and install it. I'm using the most recent version and it's coming up as v.4.0.20710.0. That should grab all the dependencies you need.

Also if you used to be using MVC3 and are now trying to use MVC4 you'll want to go into your web.config(s) and update their references to point to the 4.0 version of MVC. If you're not sure, you can always create a fresh MVC4 app and copy the web.config from there. Don't forget the web.config in your Views/Areas folders if you do.

UPDATE: I've found that what you need to have is the Nuget package Microsoft.AspNet.Web.Optimization installed in your project. It's included by default in an MVC4 RTM app regardless if you specify the target framework as 4.5 or 4.0. This is the namespace that the bundling classes are included in, and doesn't appear to be dependent on the framework. I've deployed to a server that does not have 4.5 installed and it still works as expected for me. Just make sure the DLL gets deployed with the rest of your app.

ASP.NET MVC framework 4.5 CSS bundle does not work on the hosting

My guess is that the path Content/css exists on disk in your app. In this case IIS would be handling the request, not MVC.

Make sure that the virtual path for the bundle (the parameter of the StyleBundle constructor) doesn't match a folder in the file system.

From the comments:

"A good convention to follow when creating bundles is to include
"bundle" as a prefix in the bundle name. This will prevent a possible
routing conflict."



Related Topics



Leave a reply



Submit