According to an article I read earlier by Scott Guthrie, and a video posted by Mads Kristensen, I should be able to auto-bundle/minify in ASP.net MVC 4 by replacing this:
<link href="Styles/reset.css" rel="stylesheet" type="text/css" />
<link href="Styles/normalize.css" rel="stylesheet" type="text/css" />
<link href="Styles/styles.css" rel="stylesheet" type="text/css" />
<script src="Scripts/jquery-1.8.0.min.js" type="text/javascript"></script>
<script src="Scripts/jquery-validation.min.js" type="text/javascript"></script>
With this:
<link href="Styles/css" rel="stylesheet" type="text/css" />
<script src="Scripts/js" type="text/javascript"></script>
I've tried targeting both .Net 4.0 and 4.5 and it doesn't seem to make a difference. I get 404 errors and the link and script tags are never directed at the bundled resources.
Did this feature get dropped from the final version?
I'd like to utilize this feature for "Themes".
This is how I ended up implementing. Hopefully it makes sense...
/// <summary>
/// Render stylesheets HTML for the given theme. Utilizes System.Web.Optimization for bundling and minification
/// </summary>
/// <param name="themeName">Name of theme</param>
/// <returns>HtmlString containing link elements</returns>
public static IHtmlString RenderThemeStyles(string themeName)
{
IHtmlString retValue = null;
// If no theme name is passed, return null
if (!themeName.HasValue())
return retValue;
var ctxt = HttpContext.Current;
string themePath = "~/Themes/" + themeName;
string themeKey = themePath + "/css";
if (ctxt.Cache[themeKey] != null)
return (IHtmlString)ctxt.Cache[themeKey];
// Check to see if the theme directory exists. Throw error if it does not
string themeSysPath = HttpContext.Current.Server.MapPath(themePath);
DirectoryInfo themeDir = new DirectoryInfo(themeSysPath);
if (!themeDir.Exists)
throw new ApplicationException(string.Format("Theme directory \"{0}\" does not exist", themePath));
// Remove the old bundle if it already exists
var old_bundle = BundleTable.Bundles.FirstOrDefault(b => b.Path == themeKey);
if (old_bundle != null)
BundleTable.Bundles.Remove(old_bundle);
if (themeDir.GetFiles("*.css").Length > 0)
{
// If there are css files, add them to the bundler and save the rendered output to cache
Bundle styles = new StyleBundle(themeKey).IncludeDirectory(themePath, "*.css");
BundleTable.Bundles.Add(styles);
retValue = Styles.Render(themeKey);
ctxt.Cache.Insert(themeKey, retValue, new System.Web.Caching.CacheDependency(themeSysPath));
}
else
{
// If there are no css files, save empty string to cache
ctxt.Cache.Insert(themeKey, new HtmlString(string.Empty), new System.Web.Caching.CacheDependency(themeSysPath));
}
return retValue;
}
Yes, this feature is removed in the MVC4 RC version although I could not find the RC release notes anymore.
Rick Anderson 's blog post on upgrade MVC4 beta to RC describes the process:
Remove the "autobundling" references and create/copy a BundleConfig.cs
with your bundle configs and call it from Global.asax with BundleConfig.RegisterBundles(BundleTable.Bundles);
.
Hanselman mentions some backround info about the decision:
There's been some significant changes to the web optimization (minification and bundling) framework since beta. There wasn't enough control over what was bundled and in what order in the beta, so that's been moved into a BundleConfig.cs (or .vb) where you have total control
Not exactly, so we removed EnableDefaultBundles
which is what you refer to 'autobundling', but the underlying functionality is still there.
You can do the equivalent of what that method was doing by registering:
BundleTable.Bundles.Add(new DynamicFolderBundle("js", "*.js");
BundleTable.Bundles.Add(new DynamicFolderBundle("css", "*.css");
We removed the method since this is a fairly problematic approach as alphabetical ordering is not usually the desired ordering.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With