Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
275 views
in Technique[技术] by (71.8m points)

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

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

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...