Back to Home

We pass to WebMarkupMin 2.X

WebMarkupMin · .NET · .NET Core · ASP.NET · ASP.NET MVC · ASP.NET Web Forms · ASP.NET Web Pages · ASP.NET Core · Client Optimization · Minimization · Minification · HTML · XHTML · XML

We pass to WebMarkupMin 2.X

    WebMarkupMin, .NET Core, and NUglify Logos
    Last spring, when ASP.NET 5 was still in the Beta 3 phase, I began to receive letters from users asking them to make WebMarkupMin compatible with DNX 4.5.1 and DNX Core 5.0. The main problem was that the new .NET does not support the configuration using configuration files App.configand Web.config. The rewriting of WebMarkupMin.Core, WebMarkupMin.MsAjax and WebMarkupMin.Yui should not have been particularly difficult, because you just had to delete all the code using the librarySystem.Configuration. Serious problems should have arisen when rewriting ASP.NET extensions, because they needed to develop a completely new configuration model, and this, in turn, required very serious changes in the architecture. These changes affected not only the code, but also the structure of the solution and NuGet packages, so I decided to start from scratch and made a repository on GitHub . At that time, until the release of the stable version of the new ASP.NET, at least six months remained, so it was necessary to simultaneously support 2 branches of WebMarkupMin: stable 1.X on CodePlex and preliminary 2.X on GitHub.

    As everyone knows, the release of stable versions of .NET and ASP.NET Core 1.0 was delayed by a few more months and took place only at the end of June this year. Following the release of these frameworks, WebMarkupMin 2.0 was also released. In this article I will tell you about how to upgrade existing applications for WebMarkupMin 2.X, as well as how to add it to web applications written in ASP.NET Core.

    Critical changes and innovations


    In order to install WebMarkupMin 2.X packages, you need to update NuGet Package Manager to version 2.8.6 or higher.

    The basic version 2.X critical change was the refusal of the use of the file Web.configand App.configfor WebMarkupMin settings. Now, when configuring, instead of a declarative approach (using configuration files), an imperative approach (using program code) is used.

    Therefore, when upgrading WebMarkupMin to version 2.X, you need to do 2 things:

    1. Delete the package WebMarkupMin.ConfigurationIntelliSense , because it is no longer necessary.
    2. After removing obsolete packages and updating old versions of packages to new ones, you need to delete the group of configuration sections webMarkupMinand its declaration from files Web.configand App.config:


    Next, we consider the update procedure for each package separately.

    Core


    After updating the WebMarkupMin.Core package, you need to replace all namespace connections with WebMarkupMin.Core.Minifiersand WebMarkupMin.Core.Settingsin your application code WebMarkupMin.Core.

    External CSS and JS code minifiers


    Unfortunately, the WebMarkupMin.MsAjax and WebMarkupMin.Yui modules do not support .NET Core, and therefore can only be used in .NET 4.X applications, ASP.NET 4.X web applications, and ASP.NET Core web applications built on based on the ASP.NET Core Web Application (.NET Framework) template. This is because the authors of Microsoft Ajax Minifier and YUI Compressor for .NETdid not port their libraries to .NET Core. I can not say anything definite about YUI Compressor for .NET, maybe after a while it will still be ported. As for Microsoft Ajax Minifier, everything is already very clear: its development was discontinued in March 2015 (after Ron Logan left Microsoft). But not everything is so bad, because there is a fork of Microsoft Ajax Minifier called NUglify , which is compatible with .NET Core. The new version of WebMarkupMin has a package based on it - WebMarkupMin.NUglify .

    Ms ajax


    After updating the WebMarkupMin.MsAjax package, you need to replace all namespace connections with WebMarkupMin.MsAjax.Minifiersand WebMarkupMin.MsAjax.Settingsin your application code WebMarkupMin.MsAjax.

    Yui


    After updating the WebMarkupMin.Yui package, you need to replace all namespace connections with WebMarkupMin.Yui.Minifiersand WebMarkupMin.Yui.Settingsin your application code WebMarkupMin.Yui.

    Nuglify


    At the moment, the WebMarkupMin.NUglify API is completely identical to WebMarkupMin.MsAjax. Therefore, when switching from WebMarkupMin.MsAjax to WebMarkupMin.NUglify in the application code, it is enough to simply replace the prefixes MsAjaxwith NUglify.

    Extensions for integration with ASP.NET


    All packages with ASP.NET extensions for version 1.X ( WebMarkupMin.Web , WebMarkupMin.Mvc and WebMarkupMin.WebForms ) are deprecated and are not used in WebMarkupMin 2.X.

    I will list the main innovations in extensions for ASP.NET:

    1. Switching to an imperative approach to configuring extensions.
    2. Now you can associate content types (MIME types) with the corresponding markup minifier.
    3. Now it’s possible to indicate to the minimizer which pages of the site it should process.


    ASP.NET 4.X HTTP modules


    To update an ASP.NET web application that uses HTTP modules from the WebMarkupMin.Web package, you need to perform the following actions:

    1. Uninstall the WebMarkupMin.Web package.
    2. Install the WebMarkupMin.AspNet4.HttpModules package .
    3. Upgrade the remaining old WebMarkupMin packages to version 2.X.
    4. In the file Web.configyou need to replace: namespace WebMarkupMin.Web.HttpModuleswith WebMarkupMin.AspNet4.HttpModules, assembly name WebMarkupMin.Webwith WebMarkupMin.AspNet4.HttpModulesand class name CompressionModulewith HttpCompressionModule.

    The emergence of the ability to specify which pages minifikatoru it should handle, HTTP-ins HtmlMinificationModuleand XhtmlMinificationModulecan now be used together.

    ASP.NET 4.X MVC


    To update the ASP.NET MVC web application that uses the action filters from the WebMarkupMin.Mvc package, you need to do the following:

    1. Remove WebMarkupMin.Mvc and WebMarkupMin.Web packages.
    2. Install the WebMarkupMin.AspNet4.Mvc package .
    3. Upgrade the remaining old WebMarkupMin packages to version 2.X.
    4. In your application code, replace all namespace connections WebMarkupMin.Mvc.ActionFilterswith WebMarkupMin.AspNet4.Mvc.

    It is also worth noting that, unlike older versions of WebMarkupMin, in version 2.X you can apply action filters to controllers:

    …
    using System.Web.Mvc;
    using WebMarkupMin.AspNet4.Mvc;
    …
    namespace WebMarkupMin.Sample.AspNet4.Mvc4.Controllers
    {
        [CompressContent]
        [MinifyHtml]
        [MinifyXhtml]
        [MinifyXml]
        …
        public class HomeController : Controller
        {
            …
        }
    } 
    

    In addition, in version 2.X, you can apply action filters at the entire web application level. To do this, edit the file App_Start/FilterConfig.csas follows:

    using System.Web.Mvc;
    using WebMarkupMin.AspNet4.Mvc;
    namespace WebMarkupMin.Sample.AspNet4.Mvc4
    {
        public class FilterConfig
        {
            public static void RegisterGlobalFilters(GlobalFilterCollection filters)
            {
                …
                filters.Add(new CompressContentAttribute());
                filters.Add(new MinifyHtmlAttribute());
                filters.Add(new MinifyXhtmlAttribute());
                filters.Add(new MinifyXmlAttribute());
                …
            }
        }
    }

    Errors of the form “The 'MinifyXXX Attribute' attribute can not be applied to the 'XXX' action method of the 'XXX' controller, because it returns the result with not supported content type." Are also a thing of the past. Now, if the content type of the result of the action does not match the filter, then minification is simply not applied to this result.

    ASP.NET 4.X Web Forms


    To update the ASP.NET Web Forms web application that uses the page or master page classes from the WebMarkupMin.WebForms package, you must do the following:

    1. Remove WebMarkupMin.WebForms and WebMarkupMin.Web packages.
    2. Install the WebMarkupMin.AspNet4.WebForms package .
    3. Upgrade the remaining old WebMarkupMin packages to version 2.X.
    4. In your application code to replace all connections namespaces WebMarkupMin.WebForms.Pagesand WebMarkupMin.WebForms.MasterPageson WebMarkupMin.AspNet4.WebForms.

    In version 2.X, page classes were added that only support minification (without HTTP compression): MinifiedHtmlPageand MinifiedXhtmlPage. Also, the corresponding classes appeared for the master pages: MinifiedHtmlMasterPageand MinifiedXhtmlMasterPage.

    ASP.NET Core 1.X


    The new version of WebMarkupMin has an extension for ASP.NET Core - the WebMarkupMin.AspNetCore1 package . In terms of functionality, this package resembles WebMarkupMin.AspNet4.HttpModules, but instead of four HTTP modules, it contains one middleware component. The main difference between this package and WebMarkupMin.AspNet4.HttpModules is that the connection of modules (features) and their configuration are carried out in one place - in the file Startup.cs.

    Consider an example of connecting modules:

    using Microsoft.AspNetCore.Builder;
    using Microsoft.AspNetCore.Hosting;
    using Microsoft.Extensions.Configuration;
    using Microsoft.Extensions.DependencyInjection;
    using Microsoft.Extensions.Logging;
    using WebMarkupMin.AspNetCore1;
    namespace TestAspNetCore1
    {
        public class Startup
        {
            …
            // This method gets called by the runtime.
            // Use this method to add services to the container.
            public void ConfigureServices(IServiceCollection services)
            {
                …
                // Add WebMarkupMin services.
                services.AddWebMarkupMin()
                    .AddHtmlMinification()
                    .AddXmlMinification()
                    .AddHttpCompression()
                    ;
                // Add framework services.
                services.AddMvc();
            }
            // This method gets called by the runtime.
            // Use this method to configure the HTTP request pipeline.
            public void Configure(IApplicationBuilder app, IHostingEnvironment env,
                ILoggerFactory loggerFactory)
            {
                …
                app.UseWebMarkupMin();
                app.UseMvc(routes =>
                {
                    …
                });
            }
        }
    }

    The method ConfigureServicesregisters services. Using the extension method AddWebMarkupMinand its child methods ( AddHtmlMinification, AddXmlMinificationand AddHttpCompression) we add WebMarkupMin services to the dependency injection container:

    1. The method AddWebMarkupMinregisters the following classes as singletones: ThrowExceptionLogger(interface implementation ILogger), KristensenCssMinifierFactory(interface implementation ICssMinifierFactory) and CrockfordJsMinifierFactory(interface implementation IJsMinifierFactory). By itself, this method does not connect a single module (feature), for this purpose its child methods are used. For example, if you do not call the method AddHtmlMinification, then HTML minification will not be available.
    2. The method AddHtmlMinificationregisters the class HtmlMinificationManager(implementation of the interface IHtmlMinificationManager) as a singleton. There is also a similar method - AddXhtmlMinificationthat registers a class XhtmlMinificationManageras an implementation of an interface IXhtmlMinificationManager.
    3. The method AddXmlMinificationregisters the class XmlMinificationManager(implementation of the interface IXmlMinificationManager) as a singleton.
    4. The method AddHttpCompressionregisters the class HttpCompressionManager(implementation of the interface IHttpCompressionManager) as a singleton.

    The method Configureregisters middleware components. Using the extension method, UseWebMarkupMinwe add the class WebMarkupMinMiddlewareto the ASP.NET pipeline. A call to this method must be made immediately before a method call UseMvc, because the component RouterMiddlewareends the chain of calls.

    Thus, we added HTML minification, XML minification and HTTP compression to our web application. In the “ASP.NET Core Extensions Configuration Model” section, we will look at how to configure and override added services.

    The basic configuration model for ASP.NET extensions


    Prior to WebMarkupMin 2.X, ASP.NET extensions were configured by editing the file Web.config. Now, to configure extensions, instead of a declarative approach (using a configuration file), an imperative approach (using program code) is used.

    The rejection of the declarative approach was caused by the following reasons:

    1. For several years now, Microsoft has been using an imperative approach to customize parts of ASP.NET (such as the Web API or Web Optimization Framework).
    2. In ASP.NET Core, only limited file support remained Web.config(mainly for integration with IIS).

    Extensions for ASP.NET 4.X and ASP.NET Core 1.X use various configuration models. In ASP.NET 4.X extension settings made through special classes: WebMarkupMinConfiguration, HtmlMinificationManager, XhtmlMinificationManagerand XmlMinificationManager. In ASP.NET Core 1.X configuration extensions based on the framework, Microsoft.Extensions.Options and uses the following classes: WebMarkupMinOptions, HtmlMinificationOptions, XhtmlMinificationOptionsand XmlMinificationOptions. However, these configuration models have much in common, and their interfaces and base classes are allocated in a separate package - WebMarkupMin.AspNet.Common .

    Basic settings for ASP.NET extensions


    Classes WebMarkupMinConfigurationand WebMarkupMinOptionsinherit a class WebMarkupMinConfigurationBasethat has the following properties.
    PropertyData typeDefault valueDescription
    DisableMinificationBooleanfalseDisables minification of markup.
    DisableCompressionBooleanfalseDisables HTTP compression of text content.
    MaxResponseSizeInteger-1The maximum size of the HTTP response (in bytes) above which markup minification is disabled. If the value of this property is equal -1, then the HTTP response size is not checked.
    DisablePoweredBy­HttpHeadersBooleanfalseDisables HTTP headers *-Minification-Powered-By(e.g., header X-HTML-Minification-Powered-By: WebMarkupMin)

    This class and its subclasses are a replacement for the configuration section configuration/webMarkupMin/webExtensionsfrom the previous version of WebMarkupMin.

    Markup minification managers and options


    Minification managers are inherently customizable factories that instantiate markup minifiers. But besides this, they also contain logic that allows you to selectively apply minification (based on the type of content and URL).

    All classes of managers and markup minification options have properties IncludedPagesand ExcludedPagesthat allow you to include / exclude site pages from the processing of the minifier. These properties are of type , and by default contain empty lists, because By default, filtering is disabled and all pages are minified. There are 3 built-in interface implementations :IList

    IUrlMatcher

    1. ExactUrlMatcher. A URL is used as a template (for example, new ExactUrlMatcher("/contact")).
    2. RegexUrlMatcher. A regular expression compatible with the ECMAScript standard (for example, new RegexUrlMatcher(@"^/minifiers/x(?:ht)?ml-minifier$")) is used as a template .
    3. WildcardUrlMatcher. A template that supports Wildcard syntax is used (for example, new WildcardUrlMatcher("/minifiers/x*ml-minifier")). This syntax supports 2 metacharacters: an asterisk ( *) - matches any string of characters, even empty; and a question mark ( ?) - matches any single character.

    By default, all of the above implementations of the interface are IUrlMatchernot case sensitive. To change this behavior, you need to pass an equal value true(for example, new ExactUrlMatcher("/Contact", true)) to the constructor of the class as the second parameter .

    HTML minification manager and options


    Classes HtmlMinificationManagerand HtmlMinificationOptionshave the following general properties:
    PropertyData typeDefault valueDescription
    MinificationSettingsHtmlMinification­SettingsClass instance HtmlMinification­SettingsHTML minifier settings.
    SupportedMediaTypesISettext/htmlList of supported content types.
    IncludedPagesIListEmpty listIncludes site pages in the processing of HTML-minifier.
    ExcludedPagesIListEmpty listExcludes site pages from the processing of HTML-minifier.
    CssMinifierFactoryICssMinifierFactoryClass instance KristensenCssMinifier­FactoryCSS minifier factory.
    JsMinifierFactoryIJsMinifierFactoryClass instance CrockfordJsMinifier­FactoryFactory JS minifier.

    XHTML minification manager and options


    Classes XhtmlMinificationManagerand XhtmlMinificationOptionshave the following general properties:
    PropertyData typeDefault valueDescription
    MinificationSettingsXhtmlMinification­SettingsClass instance XhtmlMinification­SettingsXHTML minifier settings.
    SupportedMediaTypesISettext/html, application/xhtml+xmlList of supported content types.
    IncludedPagesIListEmpty listIncludes site pages in the processing of XHTML-minifier.
    ExcludedPagesIListEmpty listExcludes site pages from the XHTML minifier process.
    CssMinifierFactoryICssMinifierFactoryClass instance KristensenCssMinifier­FactoryCSS minifier factory.
    JsMinifierFactoryIJsMinifierFactoryClass instance CrockfordJsMinifier­FactoryFactory JS minifier.

    Manager and XML minification options


    Classes XmlMinificationManagerand XmlMinificationOptionshave the following general properties:
    PropertyData typeDefault valueDescription
    MinificationSettingsXmlMinification­SettingsClass instance XmlMinification­SettingsXML minifier settings.
    SupportedMediaTypesISetapplication/xml, text/xml, application/xml-dtd, application/xslt+xml, application/rss+xml, application/atom+xml, application/rdf+xml, application/soap+xml, application/wsdl+xml, image/svg+xml, application/mathml+xml, application/voicexml+xml,application/srgs+xmlList of supported content types.
    IncludedPagesIListEmpty listIncludes site pages in the XML minifier process.
    ExcludedPagesIListEmpty listExcludes site pages from XML minifier processing.

    HTTP Compression Manager


    The class is HttpCompressionManageralso a factory and is responsible for instantiating GZip and Deflate compressors. But unlike minification managers, it does not have custom properties. As well as minification managers, it contains logic that allows you to selectively use HTTP compression (only text content is compressed).

    The decision about what type of compressor to create is made based on the value of the HTTP header Accept-Encoding. If the browser supports both types of compression, then Deflate is preferred.

    ASP.NET 4.X Extension Configuration Model


    Configuring ASP.NET 4.X-extensions made through special classes: WebMarkupMinConfiguration, HtmlMinificationManager, XhtmlMinificationManagerand XmlMinificationManager(these classes are defined in the package WebMarkupMin.AspNet4.Common ).

    ASP.NET Extension Settings


    A class, WebMarkupMinConfigurationin addition to properties inherited from the class WebMarkupMinConfigurationBase, also has its own properties:
    PropertyData typeDefault valueDescription
    AllowMinification­InDebugModeBooleanfalseAllows minification of markup in debug mode.
    AllowCompression­InDebugModeBooleanfalseAllows HTTP compression of text content in debug mode.

    Debug mode is determined based on the attribute value of the debugconfiguration item configuration/system.web/compilationfrom the file Web.config:


    By default, in debug mode, minification and HTTP compression are not performed. To enable them, you need to set the above configuration properties to a value equal to trueor put the web application in release mode.

    Customization Features


    Before we talk about the features of setting extensions for ASP.NET 4.X in WebMarkupMin version 2.X, I will first give an example of settings based on a file Web.configfrom the previous version:

    … …

    Next, I will reproduce these settings using the new configuration model.

    Setting up ASP.NET 4.X extensions is much like setting up Microsoft ASP.NET Web Optimization Framework .

    In ASP.NET MVC and Web Forms web applications, WebMarkupMin is configured in the file App_Start/WebMarkupMinConfig.cs:

    using System.Collections.Generic;
    using WebMarkupMin.AspNet.Common;
    using WebMarkupMin.AspNet.Common.UrlMatchers;
    using WebMarkupMin.AspNet4.Common;
    using WebMarkupMin.Core;
    using WebMarkupMin.MsAjax;
    namespace TestAspNetMvc5
    {
        public class WebMarkupMinConfig
        {
            public static void Configure(WebMarkupMinConfiguration configuration)
            {
                configuration.AllowMinificationInDebugMode = true;
                configuration.AllowCompressionInDebugMode = true;
                IHtmlMinificationManager htmlMinificationManager = HtmlMinificationManager.Current;
                htmlMinificationManager.ExcludedPages = new List
                {
                    new WildcardUrlMatcher("/minifiers/x*ml-minifier"),
                    new ExactUrlMatcher("/contact")
                };
                htmlMinificationManager.MinificationSettings = new HtmlMinificationSettings
                {
                    RemoveRedundantAttributes = true,
                    RemoveHttpProtocolFromAttributes = true,
                    RemoveHttpsProtocolFromAttributes = true
                };
                IXhtmlMinificationManager xhtmlMinificationManager = XhtmlMinificationManager.Current;
                xhtmlMinificationManager.IncludedPages = new List
                {
                    new WildcardUrlMatcher("/minifiers/x*ml-minifier"),
                    new ExactUrlMatcher("/contact")
                };
                xhtmlMinificationManager.MinificationSettings = new XhtmlMinificationSettings
                {
                    RemoveRedundantAttributes = true,
                    RemoveHttpProtocolFromAttributes = true,
                    RemoveHttpsProtocolFromAttributes = true
                };
                IXmlMinificationManager xmlMinificationManager = XmlMinificationManager.Current;
                xmlMinificationManager.MinificationSettings = new XmlMinificationSettings
                {
                    CollapseTagsWithoutContent = true
                };
                DefaultCssMinifierFactory.Current = new MsAjaxCssMinifierFactory(
                    new MsAjaxCssMinificationSettings { ColorNames = CssColor.Major }
                );
                DefaultJsMinifierFactory.Current = new MsAjaxJsMinifierFactory(
                    new MsAjaxJsMinificationSettings { QuoteObjectLiteralProperties = true }
                );
                DefaultLogger.Current = new MyLogger();
            }
        }
    }

    These settings are almost identical to the settings from the file Web.config, with the exception of one small detail - here is an example of the use of properties IncludedPagesand ExcludedPages(in the previous version there was no such functionality). In this example, using these properties, we divide all the pages of the site with the content type text/htmlinto 2 groups: one is processed by the HTML minifier, and the other by the XHTML minifier. Such a separation is unlikely to be useful in real life, but it shows quite clearly how to use these configuration properties.

    Another point that I would like to dwell on is the use of factories of CSS and JS minifiers. Previously, when setting up ASP.NET extensions, we specified the names of CSS and JS minifiers, but now we use factory instances instead.

    In version 1.X, when creating instances of such minificators, 3 actions were performed:

    1. Search in the configuration file for the name of the minifier for information on the corresponding .NET type.
    2. Create an instance of a .NET type.
    3. Loading minifier settings from the configuration file.

    In version 2.X, we immediately have an instance of the corresponding factory, which creates instances of minificators with the settings we need. Accordingly, there are 2 interfaces for such factories: ICssMinifierFactoryand IJsMinifierFactory. Factories always come with minifiers, i.e. Each CSS or JS minifier has its own factory.

    In this example, with the help of classes DefaultCssMinifierFactory, DefaultJsMinifierFactorywe set the factories by default. These factories will be used by minification managers only if we have not explicitly defined the factories. To explicitly assign factory instances to HTML and XHTML minification managers, the following properties are used CssMinifierFactoryand JsMinifierFactory:

    …
    using WebMarkupMin.MsAjax;
    using WebMarkupMin.Yui;
    namespace TestAspNetMvc5
    {
        public class WebMarkupMinConfig
        {
            public static void Configure(WebMarkupMinConfiguration configuration)
            {
                …
                IHtmlMinificationManager htmlMinificationManager = HtmlMinificationManager.Current;
                …
                htmlMinificationManager.CssMinifierFactory = new MsAjaxCssMinifierFactory();
                htmlMinificationManager.JsMinifierFactory = new MsAjaxJsMinifierFactory();
                IXhtmlMinificationManager xhtmlMinificationManager = XhtmlMinificationManager.Current;
                …
                xhtmlMinificationManager.CssMinifierFactory = new YuiCssMinifierFactory();
                xhtmlMinificationManager.JsMinifierFactory = new YuiJsMinifierFactory();
                …
            }
        }
    }

    In order for the settings from the file to App_Start/WebMarkupMinConfig.cstake effect, you need to add a method call WebMarkupMinConfig.Configureto the file Global.asax:

    …
    using System.Web.Routing;
    using WebMarkupMin.AspNet4.Common;
    namespace TestAspNetMvc5
    {
        public class MvcApplication : System.Web.HttpApplication
        {
            protected void Application_Start()
            {
                …
                RouteConfig.RegisterRoutes(RouteTable.Routes);
                WebMarkupMinConfig.Configure(WebMarkupMinConfiguration.Instance);
            }
        }
    }

    In ASP.NET Web Pages, instead of files App_Start/WebMarkupMinConfig.csand Global.asaxfor configuration, only one file is used - _AppStart.cshtml:

    @using WebMarkupMin.AspNet.Common
    @using WebMarkupMin.AspNet.Common.UrlMatchers
    @using WebMarkupMin.AspNet4.Common
    @using WebMarkupMin.Core
    @using WebMarkupMin.MsAjax
    @using TestAspNetWebPages3
    @{
        …
        #region WebMarkupMin configuration
        WebMarkupMinConfiguration configuration = WebMarkupMinConfiguration.Instance;
        configuration.AllowMinificationInDebugMode = true;
        configuration.AllowCompressionInDebugMode = true;
        IHtmlMinificationManager htmlMinificationManager = HtmlMinificationManager.Current;
        htmlMinificationManager.ExcludedPages = new List
        {
            new WildcardUrlMatcher("/minifiers/x*ml-minifier"),
            new ExactUrlMatcher("/contact")
        };
        htmlMinificationManager.MinificationSettings = new HtmlMinificationSettings
        {
            RemoveRedundantAttributes = true,
            RemoveHttpProtocolFromAttributes = true,
            RemoveHttpsProtocolFromAttributes = true
        };
        IXhtmlMinificationManager xhtmlMinificationManager = XhtmlMinificationManager.Current;
        xhtmlMinificationManager.IncludedPages = new List
        {
            new WildcardUrlMatcher("/minifiers/x*ml-minifier"),
            new ExactUrlMatcher("/contact")
        };
        xhtmlMinificationManager.MinificationSettings = new XhtmlMinificationSettings
        {
            RemoveRedundantAttributes = true,
            RemoveHttpProtocolFromAttributes = true,
            RemoveHttpsProtocolFromAttributes = true
        };
        IXmlMinificationManager xmlMinificationManager = XmlMinificationManager.Current;
        xmlMinificationManager.MinificationSettings = new XmlMinificationSettings
        {
            CollapseTagsWithoutContent = true
        };
        DefaultCssMinifierFactory.Current = new MsAjaxCssMinifierFactory(
            new MsAjaxCssMinificationSettings { ColorNames = CssColor.Major }
        );
        DefaultJsMinifierFactory.Current = new MsAjaxJsMinifierFactory(
            new MsAjaxJsMinificationSettings { QuoteObjectLiteralProperties = true }
        );
        DefaultLogger.Current = new MyLogger();
        #endregion
    }

    This example does not need comments, because absolutely identical to the previous one.

    ASP.NET Core Extension Configuration Model


    ASP.NET Extension Options


    A class, WebMarkupMinOptionsin addition to properties inherited from the class WebMarkupMinConfigurationBase, also has its own properties:
    PropertyData typeDefault valueDescription
    AllowMinification­InDevelopmentEnvironmentBooleanfalseAllows minification of markup in a development environment.
    AllowCompression­InDevelopmentEnvironmentBooleanfalseAllows HTTP compression of text content in a development environment.

    In the new version of ASP.NET there is no such thing as debugging mode; instead, the concept of the current environment is used . The name of the current environment is determined by the value of the environment variable ASPNETCORE_ENVIRONMENT. This variable can be set to any value, but there are 3 values that have been defined by the developer of the framework: Development, Stagingand Production.

    By default, minification and HTTP compression are disabled in the development environment. To enable them, you need to set the above configuration properties to a value equal to trueor change the name of the current environment to a different one Development.

    Customization Features


    At the beginning of the article, it was shown how to connect modules (capabilities) from the WebMarkupMin.AspNetCore1 package. In this section, we will look at how you can configure them. For customization, we will use 2 features of the new ASP.NET: the Microsoft.Extensions.Options framework and the built-in dependency injection mechanism. As an example, we will again reproduce the settings from the section “ASP.NET 4.X Extensions Configuration Model”:

    using System.Collections.Generic;
    using Microsoft.AspNetCore.Builder;
    using Microsoft.AspNetCore.Hosting;
    using Microsoft.Extensions.Configuration;
    using Microsoft.Extensions.DependencyInjection;
    using Microsoft.Extensions.Logging;
    using WebMarkupMin.AspNet.Common.UrlMatchers;
    using WebMarkupMin.AspNetCore1;
    using WebMarkupMin.Core;
    using WebMarkupMin.NUglify;
    namespace TestAspNetCore1
    {
        public class Startup
        {
            …
            // This method gets called by the runtime.
            // Use this method to add services to the container.
            public void ConfigureServices(IServiceCollection services)
            {
                …
                // Add WebMarkupMin services.
                services.AddWebMarkupMin(options =>
                    {
                        options.AllowMinificationInDevelopmentEnvironment = true;
                        options.AllowCompressionInDevelopmentEnvironment = true;
                    })
                    .AddHtmlMinification(options =>
                    {
                        options.ExcludedPages = new List
                        {
                            new WildcardUrlMatcher("/minifiers/x*ml-minifier"),
                            new ExactUrlMatcher("/contact")
                        };
                        options.MinificationSettings = new HtmlMinificationSettings
                        {
                            RemoveRedundantAttributes = true,
                            RemoveHttpProtocolFromAttributes = true,
                            RemoveHttpsProtocolFromAttributes = true
                        };
                    })
                    .AddXhtmlMinification(options =>
                    {
                        options.IncludedPages = new List
                        {
                            new WildcardUrlMatcher("/minifiers/x*ml-minifier"),
                            new ExactUrlMatcher("/contact")
                        };
                        options.MinificationSettings = new XhtmlMinificationSettings
                        {
                            RemoveRedundantAttributes = true,
                            RemoveHttpProtocolFromAttributes = true,
                            RemoveHttpsProtocolFromAttributes = true
                        };
                    })
                    .AddXmlMinification(options =>
                    {
                        options.MinificationSettings = new XmlMinificationSettings
                        {
                            CollapseTagsWithoutContent = true
                        };
                    })
                    .AddHttpCompression()
                    ;
                services.AddSingleton(new NUglifyCssMinifierFactory(
                    new NUglifyCssMinificationSettings { ColorNames = CssColor.Major }
                ));
                services.AddSingleton(new NUglifyJsMinifierFactory(
                    new NUglifyJsMinificationSettings { QuoteObjectLiteralProperties = true }
                ));
                services.AddSingleton();
                …
            }
            …
        }
    }

    It can be seen from the above code that the methods that we used to connect the modules now accept delegates as parameters through which the options are configured.

    By using dependency injection, we override the default minifier factory and logger. It can also be seen from the code that in this example we use instead of the WebMarkupMin.MsAjax package its analogue - WebMarkupMin.NUglify, which is compatible with .NET Core.

    References


    1. WebMarkupMin Project Page on GitHub
    2. WebMarkupMin Documentation Version 2.X
    3. My article “WebMarkupMin HTML Minifier - A Modern HTML Minimizer for the .NET Platform”
    4. NUglify Project Page
    5. Article by Viktor Kotsyuban “Preparing ASP.NET5, Issue No. 3 - Dependency Implementation in a New Way”
    6. The Dependency Injection section of the ASP.NET Core documentation.
    7. The “Working with Multiple Environments” section of the ASP.NET Core documentation.

    Read Next