How do I compress a Json result from ASP.NET MVC with IIS 7.5

asp.netasp.net MvcJsonIis 7Http Compression

asp.net Problem Overview


I'm having difficulty making IIS 7 correctly compress a Json result from ASP.NET MVC. I've enabled static and dynamic compression in IIS. I can verify with Fiddler that normal text/html and similar records are compressed. Viewing the request, the accept-encoding gzip header is present. The response has the mimetype "application/json", but is not compressed.

I've identified that the issue appears to relate to the MimeType. When I include mimeType="*/*", I can see that the response is correctly gzipped. How can I get IIS to compress WITHOUT using a wildcard mimeType? I assume that this issue has something to do with the way that ASP.NET MVC generates content type headers.

The CPU usage is well below the dynamic throttling threshold. When I examine the trace logs from IIS, I can see that it fails to compress due to not finding a matching mime type.

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

asp.net Solutions


Solution 1 - asp.net

Make sure your %WinDir%\System32\inetsrv\config\applicationHost.config contains these:

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

From the link of @AtanasKorchev.

As @simon_weaver said in the comments, you might be editing the wrong file with a 32 bit editor on a 64 bit Windows, use notepad.exe to make sure this file is indeed modified.

Solution 2 - asp.net

I have successfully used the approach highlighted here.

Solution 3 - asp.net

Use this guide

None of these answers worked for me. I did take note of the application/json; charset=utf-8 mime-type though.

Solution 4 - asp.net

I recommend this approach
Create CompressAttribute class, and set target action.

Solution 5 - asp.net

The ActionFilterAttribute approach updated for ASP.NET 4.x and Includes Brotli.NET package.

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);
		}
	}
}

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionGareth SaulView Question on Stackoverflow
Solution 1 - asp.netdeerchaoView Answer on Stackoverflow
Solution 2 - asp.netAtanas KorchevView Answer on Stackoverflow
Solution 3 - asp.netRyan KirkmanView Answer on Stackoverflow
Solution 4 - asp.nettakeparaView Answer on Stackoverflow
Solution 5 - asp.netseagulledgeView Answer on Stackoverflow