Web API Gzip not being applied

2019-03-12 09:07发布

I have added the web.config entry to enable gzip compression based on this S/O answer Enable IIS7 gzip.

I then checked the Chrome Developer window while loading an ASPX page and saw the header in the response:

Cache-Control:private
Content-Encoding:gzip
Content-Length:3669
Content-Type:text/html; charset=utf-8
Date:Wed, 04 Mar 2015 00:46:05 GMT
Server:Microsoft-IIS/7.5
Vary:Accept-Encoding
X-AspNet-Version:4.0.30319
X-Powered-By:ASP.NET

So that means it's "working", correct? But when looking for that header when making a Web API call, it is not present:

Cache-Control:no-cache
Content-Length:551
Content-Type:application/json; charset=utf-8
Date:Wed, 04 Mar 2015 00:53:05 GMT
Expires:-1
Pragma:no-cache
Server:Microsoft-IIS/7.5
X-AspNet-Version:4.0.30319
X-Powered-By:ASP.NET

I have tried all kinds of different configurations (starting with the one recommended in the linked S/O answer above). Finally, in an act of desperation, I set it to this, which I thought would make it try to compress all requests (everything except */* commented out):

  <httpCompression directory="%SystemDrive%\inetpub\temp\IIS Temporary Compressed Files">
    <scheme name="gzip" dll="%Windir%\system32\inetsrv\gzip.dll"/>
    <dynamicTypes>
      <add mimeType="*/*" enabled="true"/>
      <!--<add mimeType="text/*" enabled="true"/>
      <add mimeType="message/*" enabled="true"/>
      <add mimeType="application/javascript" enabled="true"/>
      <add mimeType="application/json" enabled="true"/>-->
      <!--<add mimeType="*/*" enabled="false"/> -->
    </dynamicTypes>
    <staticTypes>
      <add mimeType="*/*" enabled="true"/>
      <!--<add mimeType="text/*" enabled="true"/>
      <add mimeType="message/*" enabled="true"/>
      <add mimeType="application/javascript" enabled="true"/>
      <add mimeType="application/json" enabled="true"/>-->
      <!-- add mimeType="*/*" enabled="false"/>-->
    </staticTypes>
  </httpCompression>
  <urlCompression doStaticCompression="true" doDynamicCompression="true"/>

What can be preventing the GZIP from being applied to my Web API methods?

Update

I have since tried both the NuGet Web API Compression package, and editing the applicationHost.config in both IIS Express 8.0 (Visual Studio) and a locally-installed IIS 7.5. All have yielded the same results: requests for other mime types like text/* work, but application/json refuses to be gzipped.

7条回答
爱情/是我丢掉的垃圾
2楼-- · 2019-03-12 09:42

At first.

IIS Ignores WEB API Response compression because web api responses are of mime type

application/json; charset=utf-8

Default IIS Compression settings do not include this Mime type so they do not compress the response.

So your have to add this mime type to the <dynamicTypes> section

<add mimeType="application/json; charset=utf-8" enabled="true" />

(Or just to test it , as you did <add mimeType="*/*" enabled="true" />)

BUT

By default <httpCompression> Section is locked by IIS for settings from outside!!

So any settings you specify on your web.config will get ignored!

Unless you specify these settings on the applicationHost.config <httpCompression> section OR edit the <httpCompression> section to allow settingsfrom outside.

<section name="httpCompression" allowDefinition="MachineToApplication" overrideModeDefault="Allow" />
查看更多
\"骚年 ilove
3楼-- · 2019-03-12 09:44

Thanks to the 2 above solutions and other solutions elsewhere I figured a step by step explanation of how to get http compression working with Web API 2.2 might be beneficial as a few packages/namespaces have changed since the above posts.

1) Using nuget package manager console install the following;

Install-Package Microsoft.AspNet.WebApi.MessageHandlers.Compression

2) Inside WebApiConfig.cs add these usings;

using System.Net.Http.Extensions.Compression.Core.Compressors;
using Microsoft.AspNet.WebApi.Extensions.Compression.Server;

3) Inside WebApiConfig.cs add to the bottom of Register(HttpConfiguration config);

GlobalConfiguration.Configuration.MessageHandlers.Insert(0, new ServerCompressionHandler(new GZipCompressor(), new DeflateCompressor()));

4) Edit your web.config and inside system.webServer add;

<urlCompression doStaticCompression="true" doDynamicCompression="true" dynamicCompressionBeforeCache="true" />
<httpCompression>
    <dynamicTypes>
        <clear />
        <add enabled="true" mimeType="text/*" />
        <add enabled="true" mimeType="message/*" />
        <add enabled="true" mimeType="application/x-javascript" />
        <add enabled="true" mimeType="application/javascript" />
        <add enabled="true" mimeType="application/json" />
        <add enabled="false" mimeType="*/*" />
        <add enabled="true" mimeType="application/atom+xml" />
    </dynamicTypes>
    <staticTypes>
        <clear />
        <add enabled="true" mimeType="text/*" />
        <add enabled="true" mimeType="message/*" />
        <add enabled="true" mimeType="application/javascript" />
        <add enabled="true" mimeType="application/atom+xml" />
        <add enabled="true" mimeType="application/xaml+xml" />
        <add enabled="true" mimeType="application/json" />
        <add enabled="false" mimeType="*/*" />
    </staticTypes>
</httpCompression>

Worked first time on both local and an azure website so hopefully it works for you! Plus certainly no need to mess with applicationHost.config...

查看更多
迷人小祖宗
4楼-- · 2019-03-12 09:46

Is the WebAPI behind a Firewall, Web Proxy, Virus Protection Suite? As mentioned in Even Faster Web Sites: Performance Best Practices for Web Developers By Steve Souders This could be stripping out the headers.

查看更多
走好不送
5楼-- · 2019-03-12 09:47

According to ASP.NET Web API Compression (Ben Foster Blog) you have two options:

  1. Change your applicationHost.config and add

    to httpCompression -> dynamicTypes section.

  2. Use an delegating handler in your web api pipeline to handle the compression.
    e.g. Fabrik.Common or Microsoft ASP.NET Web API Compression Support

查看更多
Luminary・发光体
6楼-- · 2019-03-12 09:53

In your implementation of the NuGet package Microsoft.AspNet.WebApi.MessageHandlers.Compression, did you add the requisite line (below) to your App_Start\WebApiConfig.cs file? Note that is must be after all other message handlers in that same method, as per instructions on the package's home site.

GlobalConfiguration.Configuration.MessageHandlers.Insert(0, new ServerCompressionHandler(new GZipCompressor(), new DeflateCompressor()));

Here's a sample Register method from a WebApiConfig file that I used in a blog:

    public static void Register(HttpConfiguration config)
    {
        // Web API configuration and services

        // Web API routes
        config.MapHttpAttributeRoutes();

        config.Routes.MapHttpRoute(
            name: "DefaultApi",
            routeTemplate: "api/{controller}/{id}",
            defaults: new { echo = RouteParameter.Optional }
        );
        GlobalConfiguration.Configuration.MessageHandlers.Insert(0, new ServerCompressionHandler(new GZipCompressor(), new DeflateCompressor()));
    }

This is the blog post I mentioned: .Net Web API Compression

查看更多
别忘想泡老子
7楼-- · 2019-03-12 09:57

I think you have made all the homework in the server side, but the problem is in the request.

To allow the server to compress the response it's neccessary to inclue this header in the request:

Accept-Encoding: gzip, deflate

If you don't do it, no matter what you do on the server side, the response will never be compressed.

You don't specify which is your Web API client, but there is always a way to add headers in the request using the client API.

查看更多
登录 后发表回答