Web API Gzip not being applied

喜欢而已 提交于 2019-12-02 22:33:31

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.

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

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...

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.

I think @Peeticus was on the right track.

Here is what I did to make it work:

After running "Install-Package Microsoft.AspNet.WebApi.MessageHandlers.Compression" or adding it thru the GUI you need to update /App_Start/WebApiConfig.cs

The following additional using statements are required:

using Microsoft.AspNet.WebApi.MessageHandlers.Compression.Compressors;
using Microsoft.AspNet.WebApi.MessageHandlers.Compression;

Add the following inside the WebApiConfig.Register method:

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

Next in the IISExpress applicationHost.config find the <httpCompression>'s <dynamicTypes> element and the following before the default <add mimeType="/" enabled="false" />

<add mimeType="application/json" enabled="true" />

Also in the applicationHost.config update <urlCompression /> to

<urlCompression doDynamicCompression="true" />

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" />

The problem you are seeing is because as the documentation states https://github.com/azzlack/Microsoft.AspNet.WebApi.MessageHandlers.Compression responses less than 860 bytes are NOT compressed, and your example show "Content-Length:551". Send some more data and it should work just fine.

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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!