In my post on getting started with ASP.NET MVC’s Bundler, we looked at a couple of methods that allow you to include files and directories to include as part of a bundle. Unfortunately, there’s a serious gotcha with
IncludeDirectory() that we’ll see—and correct!—in this post.
You keep using that word…
Let’s say we have a directory structure like this (in this example, files for an Ember application):
Logically, we’d want to include both of the “account” controllers. This can be easily done with a call to
IncludeDirectory(), specifying the full (relative) path and a search filter:
This approach is fine for smaller apps with only a few of these ”feature” subfolders, but quickly becomes unmanageable with a more complex system:
One option, and the one we’ll discuss here, is to bundle all of the files in all of the folders under
~/app/controllers together. If you poke around the
Bundle class’s methods, you may notice that the
IncludeDirectory() method has a
searchSubdirectories parameter on an overload that sounds like it would do exactly that.
.IncludeDirectory("~/app/controllers/account", "*.js", true)
// ^ the overload
Unfortunately, what’s output isn’t really all that helpful:
Can you spot the problem? While all of the path’s subdirectories are searched, the subfolder structure isn’t respected when the bundler compiles the paths to output to the page. Our
login controllers aren’t children of the
controllers folder, but rather its subfolders, so the above references will return a 404 (“not found”) error. (Frankly, I can’t think of a reason why this parameter exists, but if you’ve used it, let me know in the comments!)
Building a better recursor
One potential solution is to build our own directory recursor using
DirectoryInfo. Keep in mind that MVC’s bundler uses application-relative URLs (that begin with
DirectoryInfo needs absolute, file path URLs (e.g.
C:\dev\...). In this implementation, we’re using
Server.MapPath() and a simple string replacement to swap between the two:
public static class BundleExtensions
public static Bundle IncludeSubdirectoriesOf(
this Bundle bundle,
string path, string searchPattern)
// Get the current and root paths for `DirectoryInfo`.
var absolutePath = HttpContext.Current.Server.MapPath(path);
var rootPath = HttpContext.Current.Server.MapPath("~/");
var directoryInfo = new DirectoryInfo(absolutePath);
foreach (var directory in directoryInfo.GetDirectories())
// Swap out the absolute path format for a URL.
var directoryPath = directory.FullName;
directoryPath = directoryPath
Once we incorporate our new directory searching function (implemented as an extension method so we don’t break the option for method chaining), we can organize our files however we’d like, and they come out just fine:
If you’ve used other ways of including subdirectories in a bundle, or if you have intimate knowledge of why the
Fun with Stateful CSS: Tabs
searchSubdirectories parameter even exists, let me know in the comments! Happy bundling!