Configuring IIS 7.5 to send JSON responses gzipped, NO_MATCHING_CONTENT_TYPE
Asked Answered
T

1

23

So I'm trying to get my app to send its JSON responses using dynamic compression and gzip. Unfortunately this isn't working. All the static compression on the server is working fine, but not dynamic.

I've set this up by adding:

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

To the <dynamicTypes> section of <httpCompression> in the applicationHost.config file. I'm using Charles to inspect HTTP requests and I can verify that I'm sending the requests with the Accept-Encoding: gzip, deflate header set. I've tried with both Accept: */* and Accept: application/json. When it wasn't working I enabled 'Failed Request' trace logging to find the error code for DYNAMIC_COMPRESSION_NOT_SUCCESS, which was NO_MATCHING_CONTENT_TYPE.

I've been trying to research on forums and Google, but all I can see is people saying that using the mimeType with the charset specified fixes the problem for them, but in my case it's still not working and I can verify that the response comes back with a header saying Content-Type: application/json; charset=utf-8

The endpoints that serve the JSON responses are standard .NET ASMX WebServices annotated with [ScriptService()] at the class and [ScriptMethod(UseHttpGet = true, ResponseFormat = ResponseFormat.Json)] at the method. They return JSON fine, but I can't get the dynamic compression to work for the life of me.

Since these are regular web methods as well I also added:

<add mimeType="text/xml" enabled="true" />
<add mimeType="text/xml; charset=utf-8" enabled="true" />

To attempt to gzip the XML responses. What's frustrating is that this compression works while sending JSON from the same method doesn't. At this point I'm kindof at a loss.

Thunderstruck answered 23/7, 2012 at 17:49 Comment(0)
B
36

You want to make sure that the */* mime type is after the types you add. Also make sure that you have installed Dynamic Compression Module using Server Manager (or OptionalFeatures.exe)

This is the command lines I use to make sure a good compression is done. (but make sure you actually have installed Dynamic and Static Compression modules):

call %windir%\system32\inetsrv\appcmd.exe set config -section:system.webServer/serverRuntime /frequentHitThreshold:"1"
call %windir%\system32\inetsrv\appcmd.exe set config -section:system.webServer/urlCompression /doDynamicCompression:"True"

call %windir%\system32\inetsrv\appcmd.exe set config -section:system.webServer/httpCompression /-"dynamicTypes.[mimeType='application/json']"
call %windir%\system32\inetsrv\appcmd.exe set config -section:system.webServer/httpCompression /+"dynamicTypes.[mimeType='application/json',enabled='True']"

call %windir%\system32\inetsrv\appcmd.exe set config -section:system.webServer/httpCompression /-"dynamicTypes.[mimeType='application/json; charset=utf-8']"
call %windir%\system32\inetsrv\appcmd.exe set config -section:system.webServer/httpCompression /+"dynamicTypes.[mimeType='application/json; charset=utf-8',enabled='True']"

call %windir%\system32\inetsrv\appcmd.exe set config -section:system.webServer/httpCompression /-"dynamicTypes.[mimeType='application/javascript']"
call %windir%\system32\inetsrv\appcmd.exe set config -section:system.webServer/httpCompression /+"dynamicTypes.[mimeType='application/javascript',enabled='True']"

call %windir%\system32\inetsrv\appcmd.exe set config -section:system.webServer/httpCompression /-"dynamicTypes.[mimeType='application/x-javascript']"
call %windir%\system32\inetsrv\appcmd.exe set config -section:system.webServer/httpCompression /+"dynamicTypes.[mimeType='application/x-javascript',enabled='True']"

call %windir%\system32\inetsrv\appcmd.exe set config -section:system.webServer/httpCompression /-"dynamicTypes.[mimeType='application/x-javascript; charset=utf-8']"
call %windir%\system32\inetsrv\appcmd.exe set config -section:system.webServer/httpCompression /+"dynamicTypes.[mimeType='application/x-javascript; charset=utf-8',enabled='True']"

call %windir%\system32\inetsrv\appcmd.exe set config -section:system.webServer/httpCompression /-"dynamicTypes.[mimeType='*/*']"
call %windir%\system32\inetsrv\appcmd.exe set config -section:system.webServer/httpCompression /+"dynamicTypes.[mimeType='*/*',enabled='False']"

call %windir%\system32\inetsrv\appcmd.exe set config -section:system.webServer/httpCompression /-"staticTypes.[mimeType='application/javascript']"
call %windir%\system32\inetsrv\appcmd.exe set config -section:system.webServer/httpCompression /+"staticTypes.[mimeType='application/javascript',enabled='True']"

call %windir%\system32\inetsrv\appcmd.exe set config -section:system.webServer/httpCompression /-"staticTypes.[mimeType='application/x-javascript']"
call %windir%\system32\inetsrv\appcmd.exe set config -section:system.webServer/httpCompression /+"staticTypes.[mimeType='application/x-javascript',enabled='True']"

call %windir%\system32\inetsrv\appcmd.exe set config -section:system.webServer/httpCompression /-"staticTypes.[mimeType='application/x-javascript; charset=utf-8']"
call %windir%\system32\inetsrv\appcmd.exe set config -section:system.webServer/httpCompression /+"staticTypes.[mimeType='application/x-javascript; charset=utf-8',enabled='True']"

call %windir%\system32\inetsrv\appcmd.exe set config -section:system.webServer/httpCompression /-"staticTypes.[mimeType='*/*']"
call %windir%\system32\inetsrv\appcmd.exe set config -section:system.webServer/httpCompression /+"staticTypes.[mimeType='*/*',enabled='False']"

call %windir%\system32\inetsrv\appcmd.exe set config -section:system.webServer/httpCompression /noCompressionForHttp10:"False" /noCompressionForProxies:"False" /minFileSizeForComp:"2700"

After running this your %windir%\system32\inetsrv\config\ApplicationHost.config should look something like (note that / is at the bottom):

<httpCompression directory="%SystemDrive%\inetpub\temp\IIS Temporary Compressed Files" minFileSizeForComp="2700" noCompressionForHttp10="false" 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/json" enabled="true" />
        <add mimeType="application/json; charset=utf-8" enabled="true" />
        <add mimeType="application/javascript" enabled="true" />
        <add mimeType="application/x-javascript" enabled="true" />
        <add mimeType="application/x-javascript; charset=utf-8" enabled="true" />
        <add mimeType="*/*" enabled="false" />
    </dynamicTypes>
    <staticTypes>
        <add mimeType="text/*" enabled="true" />
        <add mimeType="message/*" enabled="true" />
        <add mimeType="application/atom+xml" enabled="true" />
        <add mimeType="application/xaml+xml" enabled="true" />
        <add mimeType="application/javascript" enabled="true" />
        <add mimeType="application/x-javascript" enabled="true" />
        <add mimeType="application/x-javascript; charset=utf-8" enabled="true" />
        <add mimeType="*/*" enabled="false" />
    </staticTypes>
</httpCompression>
Brennan answered 4/3, 2013 at 17:49 Comment(6)
Thanks, I had actually solved this some time ago on my own but I couldn't remember how I did it and have since left the company I was at at the time. I do believe now it was using a script with those commands and integrating it into the MSBuild definition for the application's deployment.Thunderstruck
I spent the whole day googling why compression wasn't working for me. For some reason, only running your script solved my problem (setting the same directly in the apphost file didn't). Thanks!Cercus
Why do you have the same MIME types in both the static and dynamic sections?Thrasonical
These script calls saved my life today. I actually had that section already in appHost.config... but as I was applying each line of the script, it was saying it could not find the element. So this modified something else, not sure where, but it works!Hobie
Adding this solved it for me: <add mimeType="application/json; charset=utf-8" enabled="true" />Ingenious
@carlos-aguilar-mares Do you know how can we achieve the same if we want to add httpcompression and mime in specific web.config fileSouthwards

© 2022 - 2024 — McMap. All rights reserved.