Tag Archives: JavaScript

Asp.Net MVC Code

Bundling single & multiple files in a view for MVC 3/4

If you have been following the development of asp.net mvc 4 you’ll be aware of the new bundling/minification feature; I won’t go in to detail how it works or how to use it as there are plenty of other sources for that.

I’m working on an existing MVC 3 project that is quite large has has a mixture of css, less and js dotted about with a minification system that works ok; so I was looking for a way to use the the new bundling feature in the existing project. Luckily the feature is available on nuget via the Microsoft.Web.Optimization package and there is a project called Bundle Transformer that extends the functionality.

The problem arises in registering a new bundle, the existing organisation doesn’t allow the use of the dynamic folder bundle and the front end devs want to avoid writing back end code as much as possible.

To solve this problem I developed a small bit of code that allows you to register a bundle right in the view (this is assuming you are following the Bundle Transformer documentation and have a “BundleConfig.cs” file in the App_Start folder):

 private static void RegisterBundle(string virtualPath, bool css, params string[] files)
    {
      var existing = BundleTable.Bundles.GetBundleFor(virtualPath);
      if (existing != null)
      {
        return;
      }

      var newBundle = new Bundle(virtualPath);
      foreach (var file in files)
      {
        newBundle.Include(file);
      }

      var nullOrderer = new NullOrderer();
      newBundle.Orderer = nullOrderer;

      if (css)
      {
        var cssTransformer = new CssTransformer();
        var cssMinifier = new CssMinify();
        newBundle.Transforms.Add(cssTransformer);
        newBundle.Transforms.Add(cssMinifier);
      }
      else
      {
        var jsTransformer = new JsTransformer();
        var jsMinifier = new JsMinify();
        newBundle.Transforms.Add(jsTransformer);
        newBundle.Transforms.Add(jsMinifier);
      }

      BundleTable.Bundles.Add(newBundle);
    }

    public static IHtmlString RegisterScript(string virtualPath, params string[] files)
    {
      RegisterBundle(virtualPath, false, files);
      return Scripts.Render(virtualPath);
    }

    public static IHtmlString RegisterStyle(string virtualPath, params string[] files)
    {
      RegisterBundle(virtualPath, true, files);
      return Styles.Render(virtualPath);
    }

    public static IHtmlString RegisterScriptUrl(string virtualPath, params string[] files)
    {
      RegisterBundle(virtualPath, false, files);
      return Scripts.Url(virtualPath);
    }

    public static IHtmlString RegisterStyleUrl(string virtualPath, params string[] files)
    {
      RegisterBundle(virtualPath, true, files);
      return Styles.Url(virtualPath);
    }

And now the front end devs can register a bundle in the view:

@BundleConfig.RegisterStyle("~/css/common-loggedin",
    "~/Content/less/global.less",
   "~/Content/css/transforms.css",
   "~/Content/css/ui-darkness/jquery-ui.custom.css",
   "~/Content/css/jquery.qtip.css" ,
   "~/Content/css/chosen.css" 
   )
	<link rel="stylesheet" href="@BundleConfig.RegisterStyleUrl("~/css/print","~/Content/less/print.less")" media="print" />

 @BundleConfig.RegisterScript("~/script/application",
        "~/Content/js/application.js"  , 
        "~/Content/js/thap/notifications.js"   
    )

The first parameter defines the bundle name, the rest are the files you want to include.

Asp.Net MVC

Minify CSS & JS With MVCContrib

I was doing a bit of research recently trying to find a way to compress, combine and minify css and js in Asp.Net MVC 2 and found a few ideas on the subject. The one that caught my eye was the MvcContrib IncludeHandling; a little hidden gem.

Getting it up a running however wasn’t so straight forward (there isn’t much documentation about it, or at least not much I could find.). The first problem I stumbled upon was the HtmlExtensions (RenderIncludes function) required a dependency resolver which the project I was on didn’t use. To get round this I simply copied the source (from the HtmlExtensions link) and replaced the dependency resolver with the projects IoC framework (in this case we’re using MvcTurbine with Ninject)

Next you need to register the dependency with your IoC of choice, like I said previously we’re using MvcTurbine so this is how I did with with a service registration.

namespace YourProject.MvcSite.Registration
{
  using System.Web;
  using MvcContrib;
  using MvcContrib.IncludeHandling;
  using MvcContrib.IncludeHandling.Configuration;
  using MvcTurbine.ComponentModel;

  /// <summary>
  /// Regisers the minify interfaces
  /// </summary>
  public class MinifyRegistration  : IServiceRegistration 
  {
    /// <summary>
    /// Registers the components with the specified <see cref="T:MvcTurbine.ComponentModel.IServiceLocator"/> instance.
    /// </summary>
    /// <param name="locator">Instance of <see cref="T:MvcTurbine.ComponentModel.IServiceLocator"/> to use.</param>
    public void Register(IServiceLocator locator)
    {
      var httpContext = new HttpContextProvider(HttpContext.Current);
      var handler = new IncludeHandlingSectionHandler();
      var reader = new IncludeReader(httpContext);
      var storage = new StaticIncludeStorage(new KeyGenerator());
 
      locator.Register<IIncludeHandlingSettings>(handler);
      locator.Register<IIncludeCombiner>(new IncludeCombiner(handler, reader, storage, httpContext));
    }
  }
}

The final step is to select the js/css files you want and then combine them. In the example below we’re using the T4MVC template to generate the static file links which and the code is used in a view (in our example it’s the site master view).

    <%
      var scripts = new List<string>
                      {
                        "~" + Links.Scripts.jquery_1_4_2_min_js,
                        "~" + Links.Scripts.jquery_ui_1_8_2_custom_min_js,
                        "~" + Links.Scripts.jquery_localscroll_1_2_7_min_js,
                        "~" + Links.Scripts.jquery_scrollTo_1_4_2_min_js,
                        "~" + Links.Scripts.jquery_serialScroll_1_2_2_min_js,
                        "~" + Links.Scripts.Ajax_js,
                        "~" + Links.Scripts.Custom_js,
                        "~" + Links.Scripts.json2_js,
                        "~" + Links.Scripts.flowplayer_3_2_3_min_js,
                        "~" + Links.Scripts.DragDrop_js,
                        "~" + Links.Scripts.Slider_js
                      };
    %>

    <%=Html.RenderJs(scripts)%>