如何使用 IIS 7.5 压缩来自 ASP.NET MVC 的 Json 结果
Posted
技术标签:
【中文标题】如何使用 IIS 7.5 压缩来自 ASP.NET MVC 的 Json 结果【英文标题】:How do I compress a Json result from ASP.NET MVC with IIS 7.5 【发布时间】:2011-01-09 10:37:27 【问题描述】:我无法让 IIS 7 正确压缩来自 ASP.NET MVC 的 Json 结果。我在 IIS 中启用了静态和动态压缩。我可以用 Fiddler 验证普通的 text/html 和类似的记录是否被压缩。查看请求,存在接受编码 gzip 标头。响应的 mimetype 为“application/json”,但未压缩。
我发现问题似乎与 MimeType 有关。当我包含mimeType="*/*"
时,我可以看到响应已正确压缩。如何在不使用通配符 mimeType 的情况下让 IIS 进行压缩?我认为这个问题与 ASP.NET MVC 生成内容类型标头的方式有关。
CPU 使用率远低于动态限制阈值。当我检查来自 IIS 的跟踪日志时,我可以看到它由于找不到匹配的 mime 类型而无法压缩。
<httpCompression directory="%SystemDrive%\inetpub\temp\IIS Temporary Compressed Files" noCompressionForProxies="false">
<scheme name="gzip" dll="%Windir%\system32\inetsrv\gzip.dll" />
<dynamicTypes>
<add mimeType="text/*" enabled="true" />
<add mimeType="message/*" enabled="true" />
<add mimeType="application/x-javascript" enabled="true" />
<add mimeType="application/json" enabled="true" />
</dynamicTypes>
<staticTypes>
<add mimeType="text/*" enabled="true" />
<add mimeType="message/*" enabled="true" />
<add mimeType="application/x-javascript" enabled="true" />
<add mimeType="application/atom+xml" enabled="true" />
<add mimeType="application/xaml+xml" enabled="true" />
<add mimeType="application/json" enabled="true" />
</staticTypes>
</httpCompression>
【问题讨论】:
我无法使用通配符 mimetype,因为我在 IE8 中遇到了一个奇怪的问题 - 当请求被 IIS 进一步压缩时,它似乎很难下载 .zip 文件。 Firefox 3.5 不受影响。 【参考方案1】:确保您的 %WinDir%\System32\inetsrv\config\applicationHost.config 包含这些:
<system.webServer>
<urlCompression doDynamicCompression="true" />
<httpCompression>
<dynamicTypes>
<add mimeType="application/json" enabled="true" />
<add mimeType="application/json; charset=utf-8" enabled="true" />
</dynamicTypes>
</httpCompression>
</system.webServer>
来自@AtanasKorchev 的link。
正如@simon_weaver 在 cmets 中所说,您可能在 64 位 Windows 上使用 32 位编辑器编辑了错误的文件,请使用 notepad.exe 确保确实修改了此文件。
【讨论】:
NTOE:如果我觉得applicationHost.config
不见了,您可能是在使用 32 位编辑器的 64 位机器上。当然,在备份后尝试记事本。 west-wind.com/weblog/posts/2008/Aug/09/…
几个小时,我告诉你,我已经花了几个小时试图找出为什么我的 gzip 压缩应用程序/json 没有从我的 IIS 中出来......这终于奏效了!谢谢!
不要忘记对应用程序池进行回收【参考方案2】:
我已成功使用突出显示的方法here。
【讨论】:
我以前看过那篇文章,但认为它没有添加任何新的或有用的东西。好吧,似乎与其他 mime 类型不同,您需要为 IIS 7 指定内容编码来压缩来自 ASP.NET MVC 的应用程序/json 响应。说application/json
是不够的;它必须是application/json; charset=utf-8
。
NTOE:如果applicationHost.config
在我看来我想念你可能是在使用 32 位编辑器的 64 位机器上。当然,在备份后尝试记事本。 west-wind.com/weblog/posts/2008/Aug/09/…【参考方案3】:
Use this guide
这些答案都不适合我。我确实注意到了 application/json; charset=utf-8 不过是 mime 类型。
【讨论】:
+1:这对我有用,使用application/json; charset=utf-8
mime-type :o)
这对我有用,而且您需要记住重新启动服务器而不仅仅是网站。即在启动inetmgr
后点击您的服务器名称并直接前往Manage Server
部分 - 使用该重新启动而不是单个网站重新启动【参考方案4】:
我推荐this approach
创建CompressAttribute
类,并设置目标动作。
【讨论】:
只有在其他一切都失败时? IIS7+ 不应该做得更好吗? 这是一个不错的解决方案,因为您可以缓存和压缩,而 IIS 只会缓存或压缩 这也是一个很好的方法,因为压缩小消息在压缩/解压缩中的成本可能比在原始数据传输中的成本更高。为应用程序中的所有 JSON 下载设置 gzip 实际上会花费时间来处理这些较小的消息,因此仅装饰大型 (r) 下载有其优势。 更新了 archive.org 的链接【参考方案5】:针对 ASP.NET 4.x 更新的 ActionFilterAttribute 方法并包括 Brotli.NET 包。
using System;
using System.IO.Compression;
using Brotli;
using System.Web;
using System.Web.Mvc;
public class CompressFilter : ActionFilterAttribute
public override void OnActionExecuting(ActionExecutingContext filterContext)
HttpRequestBase request = filterContext.HttpContext.Request;
string acceptEncoding = request.Headers["Accept-Encoding"];
if (string.IsNullOrEmpty(acceptEncoding)) return;
acceptEncoding = acceptEncoding.ToUpperInvariant();
HttpResponseBase response = filterContext.HttpContext.Response;
if (acceptEncoding.Contains("BR"))
response.AppendHeader("Content-encoding", "br");
response.Filter = new BrotliStream(response.Filter, CompressionMode.Compress);
else if (acceptEncoding.Contains("GZIP"))
response.AppendHeader("Content-encoding", "gzip");
response.Filter = new GZipStream(response.Filter, CompressionMode.Compress);
else if (acceptEncoding.Contains("DEFLATE"))
response.AppendHeader("Content-encoding", "deflate");
response.Filter = new DeflateStream(response.Filter, CompressionMode.Compress);
【讨论】:
以上是关于如何使用 IIS 7.5 压缩来自 ASP.NET MVC 的 Json 结果的主要内容,如果未能解决你的问题,请参考以下文章
IIS 7.5、ASP.NET、模拟和访问 C:\Windows\Temp