Understanding ASP.NEt MVC Script Bundling path specification

user272671 picture user272671 · Feb 23, 2014 · Viewed 8.5k times · Source

So I am working on learning how to use the script bundling utility in MVC and I have one problem - I don't quite get how to structure the virtual path for each of my ScriptBundle objects. For instance, when using the constructor which allows one to specify a CDN, I have the following set up

in Global.asax, I have the following call

  BundleConfig.RegisterBundles(BundleTable.Bundles);

then in the BundleConfig class, I have

public static void RegisterBundles(BundleCollection bundles)
{    
    //add link to jquery on the CDN
    const string jqueryCdnPath = @"http://code.jquery.com/jquery-2.1.0.min.js";
    const string jqueryUiCdnPath = @"http://code.jquery.com/ui/1.10.4/jquery-ui.min.js";
    const string jqueryColorCdnPath = @"http://code.jquery.com/color/jquery.color-2.1.2.min.js";
    var jqueryQunitCdnPath = @"http://code.jquery.com/qunit/qunit-1.14.0.js"; 

    bundles.Add(new ScriptBundle("~/Resources/Scripts/js/jquery", jqueryCdnPath)
       .Include("~/Resources/Scripts/js/jquery/jquery-{version}.js"));
    bundles.Add(new ScriptBundle("~/Resources/Scripts/js/jquery/ui", jqueryUiCdnPath)
       .Include("~/Resources/Scripts/js/jquery/ui/j-{version}/jquery-ui.js"));
    bundles.Add(new ScriptBundle("~/Resources/Scripts/js/jquery/color", jqueryColorCdnPath)
       .Include("~/Resources/Scripts/js/jquery/color/jquery.color-{version}.js"));
    bundles.Add(new ScriptBundle("~/Resources/Scripts/js/jquery/jqueryval")
         .Include("~/Resources/Scripts/js/jquery.unobtrusive*", "~/Resources/Scripts/js/jquery.validate*"));
}

When I build and run my page however, I get the following error message on the first Add.

**Directory does not exist.
Parameter name: directoryVirtualPath
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code. 
Exception Details: System.ArgumentException: Directory does not exist.
Parameter name: directoryVirtualPath

Source File: c:\######.Web\App_Start\BundleConfig.cs    Line: 30 

Stack Trace: 


[ArgumentException: Directory does not exist.
Parameter name: directoryVirtualPath]
   System.Web.Optimization.Bundle.Include(String virtualPath, IItemTransform[] transforms) +90
   Network.Web.BundleConfig.RegisterBundles(BundleCollection bundles) inc:\######.Web.Web\App_Start\BundleConfig.cs:30
   Network.Web.MvcApplication.Application_Start() in c:\######.Web\Global.asax.cs:27

[HttpException (0x80004005): Directory does not exist.
Parameter name: directoryVirtualPath]
   System.Web.HttpApplicationFactory.EnsureAppStartCalledForIntegratedMode(HttpContext context, HttpApplication app) +9936761
   System.Web.HttpApplication.RegisterEventSubscriptionsWithIIS(IntPtr appContext, HttpContext context, MethodInfo[] handlers) +118
   System.Web.HttpApplication.InitSpecial(HttpApplicationState state, MethodInfo[] handlers, IntPtr appContext, HttpContext context) +172
   System.Web.HttpApplicationFactory.GetSpecialApplicationInstance(IntPtr appContext, HttpContext context) +336
   System.Web.Hosting.PipelineRuntime.InitializeApplication(IntPtr appContext) +296

[HttpException (0x80004005): Directory does not exist.
Parameter name: directoryVirtualPath]
   System.Web.HttpRuntime.FirstRequestInit(HttpContext context) +9915300
   System.Web.HttpRuntime.EnsureFirstRequestInit(HttpContext context) +101
   System.Web.HttpRuntime.ProcessRequestNotificationPrivate(IIS7WorkerRequest wr, HttpContext context) +254**

Are there configuration requirements that I may be missing here? Are my paths wrongly formatted?

Thanks in advance for your help.

Answer

user272671 picture user272671 · Feb 24, 2014

I figured out what the problem is. It seems the bundlecollection does not like the specification of an include directory when using a CDN. Once I removed the removed the additional include statements, the problem disappeared.

BEFORE

public static void RegisterBundles(BundleCollection bundles)
{    
    //add link to jquery on the CDN
    const string jqueryCdnPath = @"http://code.jquery.com/jquery-2.1.0.min.js";
    const string jqueryUiCdnPath = @"http://code.jquery.com/ui/1.10.4/jquery-ui.min.js";
    const string jqueryColorCdnPath = @"http://code.jquery.com/color/jquery.color-2.1.2.min.js";
    var jqueryQunitCdnPath = @"http://code.jquery.com/qunit/qunit-1.14.0.js"; 

    bundles.Add(new ScriptBundle("~/Resources/Scripts/js/jquery", jqueryCdnPath)
       .Include("~/Resources/Scripts/js/jquery/jquery-{version}.js"));
    bundles.Add(new ScriptBundle("~/Resources/Scripts/js/jquery/ui", jqueryUiCdnPath)
       .Include("~/Resources/Scripts/js/jquery/ui/j-{version}/jquery-ui.js"));
    bundles.Add(new ScriptBundle("~/Resources/Scripts/js/jquery/color", jqueryColorCdnPath)
       .Include("~/Resources/Scripts/js/jquery/color/jquery.color-{version}.js"));
    bundles.Add(new ScriptBundle("~/Resources/Scripts/js/jquery/jqueryval")
         .Include("~/Resources/Scripts/js/jquery.unobtrusive*", "~/Resources/Scripts/js/jquery.validate*"));
}

AFTER

public static void RegisterBundles(BundleCollection bundles)
{    
    //add link to jquery on the CDN
    const string jqueryCdnPath = @"http://code.jquery.com/jquery-2.1.0.min.js";
    const string jqueryUiCdnPath = @"http://code.jquery.com/ui/1.10.4/jquery-ui.min.js";
    const string jqueryColorCdnPath = @"http://code.jquery.com/color/jquery.color-2.1.2.min.js";
    var jqueryQunitCdnPath = @"http://code.jquery.com/qunit/qunit-1.14.0.js"; 

    bundles.Add(new ScriptBundle("~/Resources/Scripts/js/jquery", jqueryCdnPath));
    bundles.Add(new ScriptBundle("~/Resources/Scripts/js/jquery/ui", jqueryUiCdnPath));
    bundles.Add(new ScriptBundle("~/Resources/Scripts/js/jquery/color", jqueryColorCdnPath));
    bundles.Add(new ScriptBundle("~/Resources/Scripts/js/jquery/jqueryval")
         .Include("~/Resources/Scripts/js/jquery.unobtrusive*", "~/Resources/Scripts/js/jquery.validate*"));
}

So, when you specify you want to use a CDN, do not bother including any local file paths, it seems.