4

I would like to configure HTML minification to my ASP>NET MVC5 web application.

I installed Nuget

Install-Package WebMarkupMin.Mvc

Then I add Filter Attributte:

[MinifyHtmlAttribute]
public ActionResult Index()
{           
    return View();
}  

But the HTML minification does not work.

Nuget Installation add few lines to the web.config:

<sectionGroup name="webMarkupMin">
      <section name="core" type="WebMarkupMin.Core.Configuration.CoreConfiguration, WebMarkupMin.Core" />
      <section name="webExtensions" type="WebMarkupMin.Web.Configuration.WebExtensionsConfiguration, WebMarkupMin.Web" />
</sectionGroup>

<webMarkupMin xmlns="http://tempuri.org/WebMarkupMin.Configuration.xsd">
  <core>
    <css>
      <minifiers>
        <add name="NullCssMinifier" displayName="Null CSS Minifier" type="WebMarkupMin.Core.Minifiers.NullCssMinifier, WebMarkupMin.Core" />
        <add name="KristensenCssMinifier" displayName="Mads Kristensen's CSS minifier" type="WebMarkupMin.Core.Minifiers.KristensenCssMinifier, WebMarkupMin.Core" />
      </minifiers>
    </css>
    <js>
      <minifiers>
        <add name="NullJsMinifier" displayName="Null JS Minifier" type="WebMarkupMin.Core.Minifiers.NullJsMinifier, WebMarkupMin.Core" />
        <add name="CrockfordJsMinifier" displayName="Douglas Crockford's JS Minifier" type="WebMarkupMin.Core.Minifiers.CrockfordJsMinifier, WebMarkupMin.Core" />
      </minifiers>
    </js>
    <html whitespaceMinificationMode="Medium" removeHtmlComments="true"
          removeHtmlCommentsFromScriptsAndStyles="true"
          removeCdataSectionsFromScriptsAndStyles="true"
          useShortDoctype="true" useMetaCharsetTag="true"
          emptyTagRenderMode="NoSlash" removeOptionalEndTags="true"
          removeTagsWithoutContent="false" collapseBooleanAttributes="true"
          removeEmptyAttributes="true" attributeQuotesRemovalMode="Html5"
          removeRedundantAttributes="true"
          removeJsTypeAttributes="true" removeCssTypeAttributes="true"
          removeHttpProtocolFromAttributes="false"
          removeHttpsProtocolFromAttributes="false"
          removeJsProtocolFromAttributes="true"
          minifyEmbeddedCssCode="true" minifyInlineCssCode="true"
          minifyEmbeddedJsCode="true" minifyInlineJsCode="true"
          processableScriptTypeList="" minifyKnockoutBindingExpressions="false"
          minifyAngularBindingExpressions="false" customAngularDirectiveList="" />
    <logging>
      <loggers>
        <add name="NullLogger" displayName="Null Logger" type="WebMarkupMin.Core.Loggers.NullLogger, WebMarkupMin.Core" />
        <add name="ThrowExceptionLogger" displayName="Throw exception logger" type="WebMarkupMin.Core.Loggers.ThrowExceptionLogger, WebMarkupMin.Core" />
      </loggers>
    </logging>
  </core>
</webMarkupMin>

The html element was added by me manually according to documentation.

Am I missing something?

3 Answers 3

11

Web application may be in debug mode. In order to switch it to release mode you need to edit the Web.config file:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
    ...
    <system.web>
        <compilation debug="false" ... />
        ...
    </system.web>
    ...
</configuration>

In addition, you can disable dependence on web application mode. Using the following settings:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
    ...
    <webMarkupMin xmlns="http://tempuri.org/WebMarkupMin.Configuration.xsd">
        <webExtensions disableMinificationInDebugMode="false"
            disableCompressionInDebugMode="false" />
        ...
    </webMarkupMin>
    ...
</configuration>
Sign up to request clarification or add additional context in comments.

4 Comments

Tried this, but am still not getting html minification.
@brando What version of the WebMarkupMin.Mvc package you are using?
Hi Andrey, I finally got it working. Works great! Not sure what I was doing wrong, but whatever it was I fixed it. Thank you!
If it doesn't work for someone, try to change maxResponseSize="100000" attribute in webExtensions to some bigger value, e.g. to 1000000, it should fix that issue.
1

So large library with so difficult usage and configuration... Are you sure need all this for just the HTML minification?

Create a new filter under the Filters subfolder of your project and call it CompactHtmlFilterAttribute Use the following code:

public class CompactHtmlFilterAttribute : ActionFilterAttribute
{
    public class WhitespaceFilter : MemoryStream
    {
        private string Source = string.Empty;
        private Stream Filter = null;

        public WhitespaceFilter(HttpResponseBase HttpResponseBase)
        {
            Filter = HttpResponseBase.Filter;
        }

        public override void Write(byte[] buffer, int offset, int count)
        {
            Source = UTF8Encoding.UTF8.GetString(buffer).Replace("\r", "").Replace("\n", "").Replace("\t", "");
            Filter.Write(UTF8Encoding.UTF8.GetBytes(Source), offset, UTF8Encoding.UTF8.GetByteCount(Source));
        }
    }

    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        #if DEBUG
            base.OnActionExecuting(filterContext);
        #else
            try
            {
                filterContext.HttpContext.Response.Filter = new WhitespaceFilter(filterContext.HttpContext.Response);
            }
            catch (Exception) { }
        #endif
    }
}

Pay atention on the #if DEBUG dirrective. HTML will be minified only in release configuration, while on debug the original code will be kept for the better readability.

Add this attribute to the controller methods

[CompactHtmlFilter]
public ActionResult Index()
{           
    return View();
}

and we're done.

6 Comments

This looks interesting, but I afraid that HTML minification is more complicated and replacing new lines is not allways correct and not enough. Maybe I try to inject some 3rd party library to write method of your template.
Absolutely correct :) The most of unnecessary space in HTML come from line feeds and tabs, but there are more points for the further minfication. You can remove comments, if any; you can shorten attributes from type='button' or type="button" to just type=bytton, etc. The beauty of this method is that everything is under your full control.
@AlexanderDayan : Is there any other option to implement this. Because using this I need to add attribute to all action method. Is there any way using we can add minification on all pages of site?
@Ankita You can define the filer scope as global and then apply it to all the actions. See the thread stackoverflow.com/questions/3334324/… for more information.
@AlexanderDayan : I have written code like this in Global.asax.cs in Application_Start() method to globally work: GlobalFilters.Filters.Add(new MinifyHtmlAttribute()); But it gives me an error Filtering is not allowed.
|
1

You need to add the following to enable the webextensions (from the doc):

<webMarkupMin xmlns="http://tempuri.org/WebMarkupMin.Configuration.xsd">
  …
  <webExtensions enableMinification="true" disableMinificationInDebugMode="true"
     enableCompression="true" disableCompressionInDebugMode="true"
     maxResponseSize="100000" disableCopyrightHttpHeaders="false" />
  …
</webMarkupMin>

Note that it's outside the <core> element.

also in your view markup you should have the attribute as:

[MinifyHtml]

Itshouldn't have the ..Attribute at the end of it.

1 Comment

in your answer I found maxResponseSize parameter. it looks like that default value is 100000 for maxResponseSize, and in my case minification and compression didn't work. it started working only when I changed maxResponseSize to 1000000. Thanks!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.