How do I get System.Web.Optimization bundles to work with custom folders in an IIS virtual directory?
Asked Answered
G

2

11

I have an asp.net mvc4. I have modules that are deployed as subdirectories within this application using IIS Virtual Directories and I need to reference files in these modules. These module dlls are registering bundles. But the bundles are not generating anything into the html page.

From this post, is-it-possible-to-unit-test-bundleconfig-in-mvc4 , I see that internally the bundles are using Server.MapPath. So it seems like it should work.

I hooked BundleTable.MapPathMethod and even called Server.MapPath myself which does correctly resolve to the right physical directory. But it still won't render anything into the html page.

Then there was this post, why-does-resolvebundleurl-not-work-for-custom-folders , that mentioned an "AddDirectory" function for custom folders BUT this function is no longer available in the most recent optimization library.

I've also tried making use of the new "IncludeDirectory" method, but that didn't work either

ScriptBundle scriptBundle = new ScriptBundle("~/bundles/jquery");
scriptBundle.IncludeDirectory(basePath + "/Scripts/","jquery-1.*");
bundles.Add(scriptBundle);

Anything else I can try to make this work?


8/27/12

PROBLEM ANSWERED: Basically System.Web.Optimization doesn't work with web urls that are sub IIS virtual directories.

The problem are these lines of code inside BundleResolver.GetBundleContents

string mapPathMethod = this.MapPathMethod("~/");
if (!file.FullName.StartsWith(mapPathMethod, StringComparison.OrdinalIgnoreCase))

that basically assumes every single file being bundled will be in a PHYSICAL folder underneath the primary web application PHYSICAL folder.

The problem, IMO, is that the web relative url path being searched for files to include is being converted to a physical path very early on and all reference to what the relative url path used to get those physical files is thrown away.

So, to see if I could make this work, I had to decompile System.Web.Optimization to bare code and then recompile again so I could "fix" it. First step was to add a RelativePath property to BundleItem, an extra constructor to BundleItem to pass down the source relative url path to preserve what the web relative search directory folder was. Then I replaced the code above with the loop before that basically tries to rematch the files found with their BundleItem so that they can be converted back to a valid web url

foreach (BundleItem bundleItem in bundleFor.Items)
{
  if (file.FullName.StartsWith(bundleItem.Path, StringComparison.OrdinalIgnoreCase)){
    string str = file.FullName.Replace(bundleItem.Path,bundleItem.RelativePath);
    str = str.Replace('\\', '/');
    strs.Add(str);
    break;
  }
}

Now my bundles are properly rendering. NOTE however that I have not yet tested this hack fix for release or with optimizations or minifying on.

I really think the asp.net team should make System.Web.Optimizations support files in IIS virtual directories. Especially now that the VS2012 has support for IIS Express that will finally make it a lot easier to build modular web apps with files being referenced via IIS Virtual Directories

Goethe answered 23/8, 2012 at 21:52 Comment(5)
Thanks for tracking this down, I'll file a bug for this issue and we'll get it fixedSplashboard
@HaoKung, do you have a reference to the bug ticket? Just need to know when we can expect to see a fix released. Thanks.Mcquiston
You can use this one: aspnetoptimization.codeplex.com/workitem/12 as this basically will be fixed as part of supporting VirtualPathProviders in general for the featureSplashboard
Check out this #19765738Magnetize
I'm trying to understand how did you solve this problem, but I can't seem to understand where is the underlying problem. #31282721 . Your answer is the closest I got, but I don't undersand how to change the things you changed in System.Web.OptimizationsSaskatchewan
S
0

AddDirectory has been renamed IncludeDirectory so you could still try that.

Splashboard answered 24/8, 2012 at 17:43 Comment(1)
I already tried that, but that didn't work either. I just tried it again to make sure, and it doens't work. I've pasted that code snippet into the OP.Goethe
A
0

You should be able to accomplish this using a virtualPathProvider if you configure it properly.

See my answer here for info on how to register it: BundleTable.Bundles.GetBundleFor() returns but not Items inside

Ardellardella answered 17/2, 2015 at 19:51 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.