title: File corrupted on download from Controller Action
body: <p>I am generating some JSON content, and then GZipping that content, before returning the gzipped content to the user, from an MVC Controller Action.</p>
  
  <p>The generation of the content, and gzipping, is working correctly as I can output the generated file to disk, and then I can open that file using GZip.  However, when the content is returned to the browser, the content has been corrupted.</p>
  
  <p>I have tried several different approaches to returning the content to the browser, such as</p>
  
  <pre><code>return File(byte[], "application/gzip");
  
  return new FileStreamResult(stream, "application/gzip")
  </code></pre>
  
  <p>And also writing directly to the Response using BinaryWrite() and WriteFile() methods</p>
  
  <p>No matter what I do, the file I receive in the browser is corrupt.</p>
  
  <p>This code shows the manner in which I am currently trying to return the file content.</p>
  
  <pre><code>// This line writes my content byte[] array to disk.  This file when opened with gzip works fine.
  System.IO.File.WriteAllBytes(@"C:\temp\test.vcp", result.FileBytes);
  
  
  // Writing out the byte array to the Response results in a corrupt file.  I have also attempted to Response.WriteFile(@"C:\temp\test.vcp") which also results in a corrupt file.
  
  Response.Clear();
  Response.ContentType = "application/gzip";
  
  Response.AppendHeader("Content-Disposition", cd.ToString());
  Response.AddHeader("Content-Length", result.FileBytes.Length.ToString());
  
  Response.BinaryWrite(result.FileBytes);
  Response.Flush();
  Response.Close();
  Response.End();
  </code></pre>
  
  <p>As the file I am creating can be written to disk, and can be read using Gzip, but the file received by the browser is corrupt, I am confident that my file creation is OK.  But somehow after writing the file to the Response, it is being corrupted.</p>
  
  <p>I did wonder if maybe some sort of HTTPHandler is manipulating the result, but I haven't added any Handlers (that I can see).</p>
  
  <p>I am running the application locally currently through IISExpress.  How can I check what HttpHandlers/HttpModules are being applied to the pipeline?</p>
  
  <p>Ultimately I expect to receive the exact same file in my browser as is written to disk.</p>
  
  <p>For reference, my generated content is 132 bytes in length, but the browser receives 216 bytes.  I have noticed when looking at the byte structure of the received data, there is a repeating pattern of 3 bytes in the content, with the values 239, 191, 189.  It almost looks like the resultant byte array has been stuffed or padded with these 3 bytes.</p>
  
  <p><strong>EDIT</strong></p>
  
  <p>Here is a standalone Action method which demonstrated the issue.</p>
  
  <pre><code>    [HttpGet]
      public void GetFile()
      {
  
          byte[] text = Encoding.ASCII.GetBytes(@"{""PetName"":""Doggy McDocFace"",""OwnerName"":""Kurt""}");
          byte[] compressed = Compress(text);
  
          var cd = new System.Net.Mime.ContentDisposition
          {
              // for example foo.bak
              FileName = "ExampleFile.vcp",
  
              // always prompt the user for downloading, set to true if you want 
              // the browser to try to show the file inline
              Inline = true,
          };
  
  
          System.IO.File.WriteAllBytes(@"C:\temp\ExampleFile.vcp", compressed);
  
  
          Response.Clear();
          Response.ContentType = "application/gzip";
  
          Response.AppendHeader("Content-Disposition", cd.ToString());
          Response.AddHeader("Content-Length", compressed.Length.ToString());
  
          Response.BinaryWrite(compressed);
          Response.Flush();
          Response.Close();
          Response.End();
      }
  
      public byte[] Compress(byte[] raw)
      {
          using (var memory = new MemoryStream())
          {
              using (var gzip = new GZipStream(memory, CompressionMode.Compress, true))
              {
                  gzip.Write(raw, 0, raw.Length);
              }
              return memory.ToArray();
          }
      }
  </code></pre>
  
  <p>Here I am spoofing my JSON content, and then compressing it.  The file written to disk works fine, and can be opened with my GZip application (I use 7-zip).  However, the file received by the browser is corrupt.  7-zip cannot recognise it as a gzip file.</p>
  
  <p><strong>EDIT 2</strong></p>
  
  <p>So it looks like (Thanks to @Will) that the content when written to Response is falling foul of UTF-8 encoding.  I cannot work out how though, as in my example above I am using Encoding.ASCII.GetBytes() to convert my string to a byte[] array.</p>
  
  <p>I've tried setting the </p>
  
  <pre><code>       Response.Charset = Encoding.ASCII.EncodingName;
         Response.ContentEncoding = Encoding.ASCII;
  </code></pre>
  
  <p>But this still doesn't result in a valid file downloaded.</p>
  
  <p><strong>Edit 3</strong></p>
  
  <p>I've narrowed down the issue to the GZip encryption of the data.  If I do not encrypt the data, then the plain text file downloads fine.  However, encrypting the byte[] array and then writing that byte[] array to the Repsonse is resulting in what seems like UTF-8 encoding issues.  Any bytes with a value over 127 are corrupted with the 3 bytes I mention further up.  I cannot work out why the Response is treating this encrypted data in this way.  My assumption is that when the Byte[] array is just plain text as a byte[] array, then this is handled fine.  As soon as it is a proper byte[] array, i.e not just a string as a byte[] array, then some other conversion of encoding is going on in the Response.</p>