title: How to return compressed data from API to the browser, and uncompress them?
body: <p>I'm creating a Web API using ASP.NET MVC.<br>
  In some cases, the data requested by the browser may be large (up to 5MB) and I'd like to compress it to speed up the process and reduce the bandwith.</p>
  
  <p>Here is my endpoint :</p>
  
  <pre><code>[RoutePrefix("Api/MyRoute")]
  public class MyController : ApiController
  {
      public IHttpActionResult Get()
      {
          /* Simplified for clarity */
  
          var data = businessLayer.FindRequiredDataFromDB()
          return Ok(data);
      }
  }
  </code></pre>
  
  <p>This works, but the amount of data is sometimes big :</p>
  
  <p><a href="https://i.stack.imgur.com/7zxqr.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/7zxqr.png" alt="Uncompressed data"></a></p>
  
  <p>In order to compress data, I created an <code>ActionFilter</code> to GZip the content :</p>
  
  <pre><code>public class CompressAttribute : ActionFilterAttribute
  {
      public override void OnActionExecuted(HttpActionExecutedContext actContext)
      {
          var content = actContext.Response.Content;
          var bytes = content == null ? null : content.ReadAsByteArrayAsync().Result;
          var zlibbedContent = bytes == null ? new byte[0] :
          CompressionHelper.DeflateByte(bytes);
          actContext.Response.Content = new ByteArrayContent(zlibbedContent);
          actContext.Response.Content.Headers.Remove("Content-Type");
          actContext.Response.Content.Headers.Add("Content-Encoding", "gzip"); /* Is that OK ? */
          actContext.Response.Content.Headers.Add("Content-Type", "application/json; charset=utf-8"); /* Same here ? */
          base.OnActionExecuted(actContext);
      }
  }
  
  public class CompressionHelper
  {
      public static byte[] DeflateByte(byte[] str)
      {
          if (str == null)
              return null;
  
          using (var output = new MemoryStream())
          {
              using (
                  var compressor = new Ionic.Zlib.GZipStream(
                      output, Ionic.Zlib.CompressionMode.Compress,
                      Ionic.Zlib.CompressionLevel.BestSpeed)
                    )
              {
                  compressor.Write(str, 0, str.Length);
              }
  
              return output.ToArray();
          }
      }
  }
  </code></pre>
  
  <p>Then decorate my API Endpoint like that :</p>
  
  <pre><code>[Compress]
  public IHttpActionResult Get()
  {
      //...
  }
  </code></pre>
  
  <p>Then, when I call this same endpoint with Postman (very same request) :</p>
  
  <p><a href="https://i.stack.imgur.com/yNwPw.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/yNwPw.png" alt="GZipped compression"></a></p>
  
  <p><strong>So it seems OK in Postman :)</strong><br>
  (size is reduced, time is longer because of a forgotten breakpoint during PrintScreen, please ignore it)</p>
  
  <p><strong>However</strong>, when called it in another app :</p>
  
  <pre><code>$.ajax({
      url: "@Url.Action("CallAPI", "Search")",
      type: "POST",
      data: JSON.stringify({ /*...*/ }),
      contentType: 'application/json',
  }).done(function(data) {
      console.log(data); /* See result below */
  });
  </code></pre>
  
  <p>Controller :</p>
  
  <pre><code>public async Task&lt;ActionResult&gt; CallAPI(/**/)
  {
      /* Simplified logic for clarity */
  
      var client = new System.Net.Http.HttpClient();
      var request = new System.Net.Http.HttpRequestMessage()
              {
                  RequestUri = new Uri(endPointURL),
                  Method = System.Net.Http.HttpMethod.Get
              };
  
      var response = client.SendAsync(request).Result;
      var data = await response.Content.ReadAsStringAsync();
      return new HttpStatusContentResult(data, HttpStatusCode.OK);
  }
  </code></pre>
  
  <p>Result send to the browser looks like this :</p>
  
  <p><a href="https://i.stack.imgur.com/KSvDr.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/KSvDr.png" alt="Compressed data"></a></p>
  
  <p>Compressed yeah, but not readable...</p>
  
  <p>I tried to unzip this content in browser using <a href="https://nodeca.github.io/pako/" rel="nofollow noreferrer">Pako</a> or other JS libraries, I can' get it work.<br>
  I'm new with APIs, did I forget something ? Could someone point me out where I'm wrong ?</p>
  
  <p>Thank you</p>