locked
403 Access denied when using Bundling RRS feed

  • Question

  • User-853298616 posted

    I just upgraded to Visual Studio 2012 RC and am using the new bundle functionality to serve CSS and Javascript files.
    This is what I have defined in my bundles:

                bundles.Add(new ScriptBundle("~/Scripts/js").Include("~/Scripts/*.js"));
    
                bundles.Add(new StyleBundle("~/Content/css").Include("~/Content/css/*.css"));
    
                bundles.Add(new StyleBundle("~/Content/themes/base/css").Include(
                            "~/Content/themes/base/jquery.ui.core.css",
                            "~/Content/themes/base/jquery.ui.resizable.css",
                            "~/Content/themes/base/jquery.ui.selectable.css",
                            "~/Content/themes/base/jquery.ui.accordion.css",
                            "~/Content/themes/base/jquery.ui.autocomplete.css",
                            "~/Content/themes/base/jquery.ui.button.css",
                            "~/Content/themes/base/jquery.ui.dialog.css",
                            "~/Content/themes/base/jquery.ui.slider.css",
                            "~/Content/themes/base/jquery.ui.tabs.css",
                            "~/Content/themes/base/jquery.ui.datepicker.css",
                            "~/Content/themes/base/jquery.ui.progressbar.css",
                            "~/Content/themes/base/jquery.ui.theme.css"));
            }

    and in my view I have this:

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

    This renders the following HTML:

    <link href="/Content/themes/base/css?v=ps9Ga9601PrzNA2SK3sQXlYmNW3igUv5FOdOPWptyus1" rel="stylesheet" type="text/css" />
    
    <link href="/Content/css?v=mF7ev-6MKuylBXvDNhyKCPCm3MzYat2U1GjFo8HsrT81" rel="stylesheet" type="text/css" />
    
    <script src="/Scripts/js?v=ScawCRjrEnEom6vyOqM0c2ZEvGNg22FaWvBxhkg9CMI1" type="text/javascript"></script>
    

    The problem is that the second CSS bundle doesn't work, and I get a "403 - Forbidden: Access is denied." error on it. Both the first CSS bundle and the JS bundle work fine.

    Any idea of what might be the problem? Thanks in advance.



    Monday, June 4, 2012 12:53 PM

Answers

  • User143145489 posted

    I guess that the path Content/css is existing on disk in your app, in this case Bundling leave the request /Content/css?v=...  to IIS to handle.

    Could you try to rename the folder css under Content? And update the path in the bundle definition?

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Monday, June 4, 2012 4:53 PM
  • User401360897 posted

    Let I try to explain you in upper level.

    Every request in ASP.NET is manged through http handlers(for example, static handler, page handler, ashx handler, etc). There is a special HTTP Module called UrlRoutingModule which matches the routes in global.asax. If a route is match then it will chnage the current http handler using HttpContext.RemapHandler method otherwise normal ASP.NET flow will continue. Similarly System.Web.Optimization insert a BundleModule http module which try to match a binding. If a match is found found then it will select the BundleHandler as http handler using HttpContext.RemapHandler method. Internally System.Web.Optimization will leave a match if HostingEnvironment.VirtualPathProvider.FileExists(path) is true or HostingEnvironment.VirtualPathProvider.DirectoryExists(path) is true.

    I am personlly suggest you to use a prefix in bundles path like,  

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

    So that no confliction will occur between bundles and routes. See this controller action,

       public class ContentController : Controller
        {
            //
            // GET: /Content/

            public ActionResult css()
            {
                return View();
            }

        }

    Clearly the default route with /content/css path matches the css action but the bundling framework will override the http handler.

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Tuesday, June 5, 2012 8:02 AM

All replies

  • User-796963942 posted

    I can't repro the issue on my side. Could you check if you can still repro the error after disabling bundling? (Change debug to true in web.config file)

    If you are using VS pro, you can check the detailed error exception by turning on exception break:

    Debug -> Exceptions -> Check break when CLR Exceptions Thrown

    Debug -> Options -> Disable Just My Code

    Monday, June 4, 2012 2:42 PM
  • User-853298616 posted

    If I disable bunding by running in Debug mode all the CSS files get imported correctly. It's only when debug is set to false in the Web.config that the problem occurs.

    Monday, June 4, 2012 2:59 PM
  • User143145489 posted

    I guess that the path Content/css is existing on disk in your app, in this case Bundling leave the request /Content/css?v=...  to IIS to handle.

    Could you try to rename the folder css under Content? And update the path in the bundle definition?

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Monday, June 4, 2012 4:53 PM
  • User-853298616 posted

    I renamed the Content/css folder to Content/styles and updated the path in the bundle definition to:

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

    I'm now getting a "The resource cannot be found." error when trying to access the URL generated by the bundler:

    Description: HTTP 404. The resource you are looking for (or one of its dependencies) could have been removed, had its name changed, or is temporarily unavailable.  Please review the following URL and make sure that it is spelled correctly. 

    Requested URL: /Content/css/

    Seems like IIS is still picking it up. I made sure that the folder is no longer in the file system, that I did a Rebuild of the solution and even stopped the site in IIS Express before running it again.

    Monday, June 4, 2012 5:16 PM
  • User143145489 posted

    could you exit IIS Express? (if in IIS sites, then run iisreset), and try again?

    Monday, June 4, 2012 5:25 PM
  • User-853298616 posted

    Ah, while writing the above reply I kept trying stuff around and finally found the problem and reached a solution.

    First I had to make sure that the virtual path for the bundle (the parameter of the StyleBundle constructor) didn't match a folder in the filesystem (thanks for that Xiaohong).

    Second, it seems that the first part of the virtual path up to the /css bit needs to match the physical path of the .css files. I'm not sure why this is the case, but it looks like the only explanation for what happens if I try to do it like in my post above.

    By changing the bundle definition to (while keeping the folder name as Content/css as I had in the beginning):

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

    and adjusting the Render call accordingly:

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

    It all works.

    My only remaining question is: is this "path-matching" an intentional feature? Because this could mean I won't be able to include files in several folders into the same bundle.




    Monday, June 4, 2012 5:30 PM
  • User143145489 posted

    in Second, it is not reqired that the first part of the virtual path up to the /css bit needs to match the physical path of the .css files.

    It should work if you use this one in the case you have Content/styles folder:

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

    the Render call:

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

    Monday, June 4, 2012 5:44 PM
  • User-853298616 posted

    Nope, that does not work. That's what I first tried when you suggested that I change the folder name, and I got the error described 2 posts above (and I did run iisreset just in case).

    Monday, June 4, 2012 5:51 PM
  • User143145489 posted

    I meant when you have Content/styles folder (rename the Content/css folder to Content/styles in your app), the below bundle should work:

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

    If it doesn't work in this case, may I have your repro?

    Basically the virtual path for the bundle should not match physical path in the filesystem, otherwise Bundling will leave request of the virtual path to IIS.

    (Bundling doesn't reqire that the first part of the virtual path up to the /css bit needs to match the physical path of the .css files.)

    Monday, June 4, 2012 6:53 PM
  • User401360897 posted

    Let I try to explain you in upper level.

    Every request in ASP.NET is manged through http handlers(for example, static handler, page handler, ashx handler, etc). There is a special HTTP Module called UrlRoutingModule which matches the routes in global.asax. If a route is match then it will chnage the current http handler using HttpContext.RemapHandler method otherwise normal ASP.NET flow will continue. Similarly System.Web.Optimization insert a BundleModule http module which try to match a binding. If a match is found found then it will select the BundleHandler as http handler using HttpContext.RemapHandler method. Internally System.Web.Optimization will leave a match if HostingEnvironment.VirtualPathProvider.FileExists(path) is true or HostingEnvironment.VirtualPathProvider.DirectoryExists(path) is true.

    I am personlly suggest you to use a prefix in bundles path like,  

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

    So that no confliction will occur between bundles and routes. See this controller action,

       public class ContentController : Controller
        {
            //
            // GET: /Content/

            public ActionResult css()
            {
                return View();
            }

        }

    Clearly the default route with /content/css path matches the css action but the bundling framework will override the http handler.

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Tuesday, June 5, 2012 8:02 AM
  • User-853298616 posted

    Thank you for the explanation of the inner workings of bundling. That definitely explains the problem I was having at the start.

    I tried to replicate my problem with renaming the physical folder from "Content/css" to "Content/styles" (while keeping the virtual path as "Content/css") in another solution and I can't. I have the same configuration on the 2 projects but my original one doesn't work properly for some reason. So this will remain as one of those bizarre problems.

    I'll follow the advice on using a "bundle" prefix in the bundles paths. No conflicts will happen that way.

    Tuesday, June 5, 2012 3:25 PM
  • User401360897 posted

    I tried to replicate my problem with renaming the physical folder from "Content/css" to "Content/styles" (while keeping the virtual path as "Content/css") in another solution and I can't. I have the same configuration on the 2 projects but my original one doesn't work properly for some reason. So this will remain as one of those bizarre problems.

    Note these requests are cached by browser.

    Tuesday, June 5, 2012 10:09 PM