Story Details for articles
StyleBundle 403 Error - Solved!
In this article, I'll show you how to build a site so that it works in Debug or Release mode using the StyleBundles and ScriptBundles. I'll demonstrate these techniques with this website template.
The Virtual Path Matters!
Apart from what you've probably heard and read in various Forums or Stackoverflow posts regarding the way to work with the StyleBundle and ScriptBundle classes, the "virtualpath" parameter of the classes DOES matter, as far as how it is named. Some answerers have gotten this right.
Let me clarify this, if you have ALL of your CSS files in the root of the Content folder, then no, it doesn't matter. It only matters if you have various folders inside the Content folder that can contain many different sets of styles for various reasons, and you want to maintain that folder structure.
I'll show you how to keep those folders without having to drop everything down to the root.
What you need to do is match the bundle name with the actual virtual path to your files!
I'll explain this in a moment, but let me show you what the framework does with the bundles from Debug mode to Release mode.
Let's say I have a Content folder with my CSS files and images in a structure like this:
This is how I want to keep my files so they are separate from each other.
So let's say I've installed the halcyonic HTML into the _Layout.cshtml page. And I've then created a StyleBundle like this:
... this will work fine in Debug mode and return a path as:
But if I were to run this in Release mode, by changing the "debug" attribute on the compilation element in the web.config file to false...
... and then run the application, I would get dreaded 403 Forbidden error and my page layout would break. And you can clearly see below that my page doesn't have any styles attached.
And this is what the path to the same image file would look like in Release mode:
Obviously we can see that the path changed when changing to Release mode, but what happened? I fuddled over this for a long time and was determined to figure it out and finally found a pattern.
If I changed the parameter name of the bundle to something that more closely matched to the actual path to the files, it started working. So if you look at the picture of the Content folder and it's file structure again, you can see that the CSS file, style.css, lives in the /Content/halcyonic/css folder.
So I tried:
Of course, each time I made a change here I had to update the Render method in the _Layout.cshtml page.
... and this too didn't work. I got the same 403 Forbidden error.
So then I found out that the last part of the virtualPath is essentially a throw away name. It doesn't really mean anything or have any other impact other than telling the framework that the information before it is important. I'll tell you why in a second.
So then I tried this:
... and it worked!
Why does this work?
Let's take a closer look at why this now works.
I've lined up the StyleBundle parameter with the included files paths to show you how they correlate with each other. Notice that they all match up to the last slash before the style sheet. This is the important thing to remember. Make the bundle parameter match the path up to the location of the style sheet, and then add a name, any name after that.
This will work:
It doesn't matter what the trailing name is. The framework will ignore it, but you need it to tell the framework that everything before it will be used as the virtualPath in Release mode. If /css was the trailing name, then it would say that it will look for the files in /Content/halcyonic, which is wrong.
And before you say, "Well why can't I put just a trailing slash after css, as in /Content/halcyonic/css/?" (notice the trailing slash). That also won't work. While the CSS will render Ok, some images may break, so put in a name with no trailing slash.
So end the virtualPath parameter with a name without a trailing slash.
Using this method will also allow you to use the relative image paths in the CSS file. One thing I've found that always works the best is to have the images folder as a child underneath the style sheet.
For KendoUI Users
To allow your KendoUI widgets to work in Release mode and Debug mode, here are the bundles and Render methods:
You would just change the version folder name to yours.
So that's essentially it! And just to be clear, this same procedure would be used for the ScriptBundle classes as well.
I know there's a lot here, but hopefully it's pretty straight forward and understandable. This should prevent you from having any more issues with getting the the CSS and Scripts to render properly in Release mode.