Implement the Microsoft Optimization Framework into Dynamicweb

This blog post is about how we can implement the Microsoft Optimization Framework within Dynamicweb and some background information about optimizing through bundling and minification.

  • April 2, 2019

Inside Dynamicweb we currently don't have a way to automatically minify or bundle stylesheets, javascript or any other resources. Using the Microsoft  Optimization Framework we can easily create bundles and minify stylesheets and javascript so that we can reduce the requests on the client to the webserver.

Why should we optimize?

So, first maybe some background information on why we actually should optimize our websites.

Significantly increase the performance of your website

  • Resources can load faster with fewer requests
  • Javascript can begin to execute sooner

Do not assume your users have a fast internet connection

  • Still millions of users on dial-up connections
  • Mobile connectivity can be spotty and costly for the user

Significantly reduce the number of requests to your server

  • Reduces your bandwith, and potentially your cost
  • Ability to support more concurrent users

Do not rely on the browser for caching resources

  • A good chunk of users to your public website will be consistently new

Development efficiencies

  • It is incredibly easy now...
  • Can save you time in development if architected correctly

Microsoft ASP.NET Optimization Library

Some facts about the Microsoft ASP.NET Optimization Library

Specifically for bundling and minifying in ASP.NET

  • It is designed for working with the .NET Framework 4.0+
  • It is open source and to be found on
  • Lives inside the System.Web.Optimization namespace
  • You can get it through NuGet -> Microsoft ASP.NET Web Optimization

Key dependencies

  • Microsoft.Web.Infrastructure
    Utility to dynamically register HTTP Modules at runtime

  • WebGrease
    Suite of tools used for optimizing Javascript, CSS and images. This suite was developed by the MSN team for

Of course there are other 3rd party libraries and frameworks that you can use such as:


  • JSMin (JS)
  • YUICompressor (JS & CSS)
  • CSSTidy (CSS)
  • AjaxMin (JS & CSS)


  • SquishIt
  • ClientDependency
  • Cassette
  • Combres

We will focus on using the ASP.NET Optimization Library and we will create the bundles and transformations all through code.

Our sample solution

The sample project I'm using is a default Dynamicweb custom solution that has no templates installed, except for the default one. We should create a custom solution to be sure we can add some code to this project. Another way would be to develop a separate library that could be referenced by our Dynamicweb solution and that should be the case when you are aiming for a solution that is redistributable.

To read more about setting up a custom Dynamicweb solution, I suggest to look at the documentation or maybe use the free open source installer tool for Dynamicweb, created by Imar Spaanjaars.

Next, I downloaded a ready to use template from to get started with a nice design.

Installing the ASP.NET Optimization Framework

To install the ASP.NET Optimization Framework, we take the easiest approach and load the packages from Nuget. You can either use the Nuget Package manager or the console to install the "Microsoft.AspNet.Web.Optimization".

One issue I run into was that when this Nuget bundle was installed, I got an error while accessing the bundle. This was due to the WebGrease package. If you run into this error you could consider the solution that was offered here:

Examining the sample solution

So, the new default template I use has a number of stylesheets and scripts that are references. I'll focus on how to bundle and minify our scripts to one bundle. This should get you started on the idea behind bundling and minification.

Inside our index.html we have the following script references:

<!-- PLUGINS -->
<script src="assets/js/plugins/source/source/jquery.bxslider.js" type="text/javascript"></script>
<script src="assets/js/plugins/source/jquery.centralized.js" type="text/javascript"></script>
<script src="assets/js/plugins/source/jquery.fixedonlater.js" type="text/javascript"></script>
<script src="assets/js/plugins/source/jquery.hashloader.js" type="text/javascript"></script>
<script src="assets/js/plugins/source/jquery.mixitup.js" type="text/javascript"></script>
<script src="assets/js/plugins/source/jquery.nav.js" type="text/javascript"></script>
<script src="assets/js/plugins/source/jquery.parallax-1.1.3.js" type="text/javascript"></script>
<script src="assets/js/plugins/source/jquery.responsivevideos.js" type="text/javascript"></script>
<script src="assets/js/plugins/source/jquery.scrollTo-" type="text/javascript"></script>
<script src="assets/js/plugins/source/jquery.tweet.js" type="text/javascript"></script>
<script src="assets/js/plugins/source/jquery.tweetCarousel.js" type="text/javascript"></script>

These script files are not minified and bundled which will result in 10 requests already for this webpage to only get the script files downloaded.

Creating a bundle

We are going to create a bundle that contains all of the script files mentioned above.

1. Create our bundle class

The first thing we do is creating a folder and name it App_Start, following the default convention that Microsoft uses when creating new WebForms or MVC projects from Visual Studio. Within this folder we create a new class and name it BundleConfig.cs. This will look like this:


Inside this class we are going to define our bundles. You can define both bundles for the script optimization as well as bundles for stylesheet optimization. You often see this happening inside the Global.asax as well.

2. Creating our script bundle

Next we will create our script bundle inside our RegisterBundles method:

/// <summary>
/// Register the bundles into the bundle collection on startup
/// </summary>
/// <param name="bundles"></param>
public static void RegisterBundles(BundleCollection bundles)

   // Create a bundle that includes all script files
   bundles.Add(new ScriptBundle("~/bundles/plugins").Include(

So we add a new ScriptBundle to the bundles collection that will registered into our application later. The first parameter is the VirtualPath to the bundle. This is the path the bundle will be accessible through in the browser. I used the name 'plugins' to keep it simple. After that, I used the Include method to specify the files I wanted to be included in my bundle.

You see me use the {version} notation at some files. This is one of the replacement functions available in the framework that will look up the latest version of this file.

3. Registering our new bundle

Now the last thing to do to get this bundle working is to register it on application start. What this means is that the RegisterBundles method should be called. This can be done in the Global.asax inside the Application_Start method.

In here we change the code to the following:

public void Application_Start(object sender, EventArgs e)

   // Register our bundle collections

   // Fires when the application is started
   Dynamicweb.Frontend.GlobalAsaxHandler.Application_Start(sender, e);


After we compile our project we should be able to access the bundle through the url like this:

To use the MVC style we should convert our templates to Razor, which then allows us to specify the bundle like this:


For this to work, we have to add a reference to the optimization namespace on top of our template:

@using System.Web.Optimization;

I'll use this approach when talking about Dynamic Folder Bundles later.

For now let's look at the 'normal' approach within Dynamicweb when you don't want to use Razor syntax.

Since the rendering engine of Dynamicweb is a bit different than a normal ASP.NET application, we have to take a different approach. In this case I use an extender called PageTemplateExtender.

In here we can override a method called ExtendTemplate and literally extend the template with our own logic.

public class CustomPageTemplateExtender : PageTemplateExtender
   public override void ExtendTemplate(Dynamicweb.Rendering.Template template)
      var scriptBundle = Scripts.Render("~/bundles/plugins").ToHtmlString();
      template.SetTag("FooterScripts", scriptBundle);

So I created a new class CustomPageTemplateExtender. In here I override the ExtendTemplate method and do two things:

  1. Create a variable in which I let the Scripts.Render method render a link to my bundle. This will result in a <link /> that can be used directly in my template.
  2. Then I assing this new variable to a Dynamicweb Tag that I have to include on my template.

Inside my template I added the following tag to the markup, just before the </body> closing tag.

<[email protected]>

Now when we compile the project and run the website, you will see the script is being rendered as follows:

<script src="/bundles/plugins?v=YHvozAsx-a22aZ93sB5Tp7fiWfkd7-t52oBb3jl2aTw1"></script>

It shows our new bundle with a time stamp for e.g. caching and version purposes.

Now when you are in debugging mode, the bundle will render the individual script files, which is good since you then are able to debug your javascript code. You can also force the optimization to be enabled always by inserting this code in for example the BundleConfig class:

BundleTable.EnableOptimizations = true;

Search for the design templates

In addition you could create bundles that will look for all files in a specific directory, which means you could search inside your current design using the Area property of the PageView and include all .css files into a new bundle.

Make it dynamic: introducing Dynamic Folder Bundles

Another approach we can make use of are Dynamic Folder Bundles, which is a feature that is mostly overlooked in configuring bundles.

  • Allows bundle transformations to be applied to folders on demand
  • Inherits from the "Bundle" class

bundles.Add(new DynamicFolderBundle("scripts", "*.js", true, new JsMinify()));

  1. The first parameter you specify is the path suffix on the url that should trigger the bundle to process.
  2. The second parameter is the search pattern and it this case it will look for all files ending with .js.
  3. The third parameter will also process files in any subdirectories.
  4. The last parameter will apply the JsMinify transformation.

So for example:

  ... will render all Javascript files bundled and minified in the solution

... will render all Javascript files under the /Content folder

So to make this work in our example, we will create a new DynamicFolderBundle for javascript files and add it to our BundleConfig class like this:

// Add a DynamicFolderBundle
bundles.Add(new DynamicFolderBundle("scripts", "*.js", true, new JsMinify()));

In our converted template, which now should have a .cshtml extension, we can refer to our bundle like this:


So we now have to follow the structure of our folders and mention the path suffix we defined in our bundle.

This will then render only the .js files inside the given folder and will apply the JsMinify transformation.


We have looked at some ways to integrate the ASP.NET Optimization Framework into Dynamicweb. There is a lot more to say about the bundling and minification that I haven't even touched yet. You could optimize your website using bundling and minification and you really should consider either using this framework or maybe one of the 3rd party frameworks I mentioned before.

It would be easy to include other powerful functionality, for example, transformations for automatically compiling LESS or SASS files before minimizing and bundling.

If you have any questions about this topic, feel free to ping me anytime!

Credits goto Travis Gosselin for his excellent course on Pluralsight on Bundling and Minification.

Image Description

Daniel Plomp

Entrepreneur, Senior Software Engineer .NET, Sitefinity Solution specialist, Orchard CMS enthusiast, Product Owner

All Author Posts

Got another minute? Check out:

Image Description

Call us

+31 (0) 36-2000196
Image Description


Grote Beer 57, 3893 DJ Zeewolde
NLThe Netherlands

Please sign in

Signin to manage your account.

Do not have an account? Signup