如何在ASP.NET MVC中配置HTML压缩

4

我希望为我的ASP.NET MVC5 web应用程序配置HTML压缩功能。

我安装了Nuget。

Install-Package WebMarkupMin.Mvc

然后我添加过滤器属性:
[MinifyHtmlAttribute]
public ActionResult Index()
{           
    return View();
}  

但是HTML缩小并没有起作用。
Nuget安装会在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>

根据文档,我手动添加了html元素。

我有遗漏什么吗?

3个回答

11

Web应用程序可能处于调试模式。如果要将其切换到发布模式,您需要编辑Web.config文件:

Web应用程序可能会在调试模式下运行。为了将其切换到发布模式,您需要编辑Web.config文件:

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

此外,您可以禁用对Web应用程序模式的依赖。使用以下设置:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
    ...
    <webMarkupMin xmlns="http://tempuri.org/WebMarkupMin.Configuration.xsd">
        <webExtensions disableMinificationInDebugMode="false"
            disableCompressionInDebugMode="false" />
        ...
    </webMarkupMin>
    ...
</configuration>

1
尝试过这个,但仍然无法获得HTML文件的最小化。 - brando
@brando,你正在使用哪个版本的WebMarkupMin.Mvc包? - Andrey Taritsyn
嗨,安德烈,我终于让它工作了。效果很棒!不确定我之前做错了什么,但无论如何我已经修复了。谢谢你! - brando
1
如果某人无法使用,请尝试将webExtensions中的maxResponseSize =“100000”属性更改为更大的值,例如1000000,这应该可以解决该问题。 - Sergey

1
如此庞大的库,使用和配置都如此困难... 你确定只为了 HTML 最小化就需要这些吗?
在项目的 Filters 子文件夹下创建一个新的过滤器,并将其命名为 CompactHtmlFilterAttribute。使用以下代码:
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
    }
}

请注意 #if DEBUG 指令。在发布配置中,HTML 将被压缩,而在调试模式下,原始代码将保留以获得更好的可读性。
将此属性添加到控制器方法中。
[CompactHtmlFilter]
public ActionResult Index()
{           
    return View();
}

我们完成了。


这看起来很有趣,但我担心HTML缩小更加复杂,并且替换换行符并不总是正确且不足够。也许我可以尝试注入一些第三方库来编写您的模板方法。 - Tomas Kubes
绝对正确 :) HTML 中大部分不必要的空格来自于换行和制表符,但在进一步压缩中还有更多的优化点。您可以删除任何注释;您可以将属性类型从 type='button' 或 type="button" 缩短为 type=button 等。这种方法的美妙之处在于它完全受到您的控制。 - Alexander Dayan
@AlexanderDayan:有没有其他的选项来实现这个?因为使用这种方法,我需要在所有操作方法中添加属性。有没有办法可以在网站的所有页面上添加缩小功能? - Ankita
@Ankita 你可以将过滤器作用域定义为全局,然后应用于所有操作。请参阅 https://dev59.com/Zk_Sa4cB1Zd3GeqP_lRm 线程获取更多信息。 - Alexander Dayan
@AlexanderDayan:我在Global.asax.cs文件的Application_Start()方法中编写了以下代码,以便全局工作: GlobalFilters.Filters.Add(new MinifyHtmlAttribute()); 但是它给我一个错误,提示“不允许过滤”。 - Ankita
@AlexanderDayan:这段代码对我不起作用。而且,如果我不想在调试模式下实现它怎么办?它应该只在IIS站点上运行。 - Ankita

1
你需要添加以下内容以启用 WebExtensions(来自文档):
<webMarkupMin xmlns="http://tempuri.org/WebMarkupMin.Configuration.xsd"><webExtensions enableMinification="true" disableMinificationInDebugMode="true"
     enableCompression="true" disableCompressionInDebugMode="true"
     maxResponseSize="100000" disableCopyrightHttpHeaders="false" /></webMarkupMin>

请注意,它位于<core>元素之外。
此外,在您的视图标记中,应将属性设置为:
[MinifyHtml]

它不应该在结尾处有..属性。


1
在你的回答中,我找到了maxResponseSize参数。看起来默认值为100000,而在我的情况下,缩小和压缩都没有起作用。只有当我将maxResponseSize更改为1000000时,它才开始工作。谢谢! - Sergey

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接