52

I wish to automatically uncompress GZiped response. I am using the following snippet:

mywebclient.Headers[HttpRequestHeader.AcceptEncoding] = "gzip";
mywebclient.Encoding = Encoding.UTF8;

try
{
    var resp = mywebclient.DownloadData(someUrl);
}

I have checked HttpRequestHeader enum, and there is no option to do this via the Headers

How can I automatically decompress the resp? or Is there another function I should use instead of mywebclient.DownloadData ?

skaffman
  • 398,947
  • 96
  • 818
  • 769
Julius A
  • 38,062
  • 26
  • 74
  • 96

2 Answers2

124

WebClient uses HttpWebRequest under the covers. And HttpWebRequest supports gzip/deflate decompression. See HttpWebRequest AutomaticDecompression property

However, WebClient class does not expose this property directly. So you will have to derive from it to set the property on the underlying HttpWebRequest.

class MyWebClient : WebClient
{
    protected override WebRequest GetWebRequest(Uri address)
    {
        HttpWebRequest request = base.GetWebRequest(address) as HttpWebRequest;
        request.AutomaticDecompression = DecompressionMethods.Deflate | DecompressionMethods.GZip;
        return request;
    }
}
feroze
  • 7,380
  • 7
  • 40
  • 57
  • 22
    Is there any specific reason to use the "excessively used" (IMHO) as-casting instead of "traditional casting" here? If you use as, you should definitely check that request is non-null, so I wonder if it wouldn't just be simpler in this case to assume that the result from GetWebRequest() is always an HttpWebRequest... – Per Lundberg Sep 12 '13 at 09:17
  • Unfortunately, this doesn't work for a WP8.1 Silverlight project. the property "AutomaticDecompression" is not available. Any ideas what I should do? Thanks! – casaout Sep 01 '15 at 15:22
32

Depending on your situation, it may be simpler to do the decompression yourself.

using System.IO.Compression;
using System.Net;

try
{
    var client = new WebClient();
    client.Headers[HttpRequestHeader.AcceptEncoding] = "gzip";
    var responseStream = new GZipStream(client.OpenRead(myUrl), CompressionMode.Decompress);
    var reader = new StreamReader(responseStream);
    var textResponse = reader.ReadToEnd();

    // do stuff

}

I created all the temporary variables for clarity. This can all be flattened to only client and textResponse.

Or, if simplicity is the goal, you could even do this using ServiceStack.Text by Demis Bellot:

using ServiceStack.Text;

var resp = "some url".GetJsonFromUrl();

(There are other .Get*FromUrl extension methods)

Aaron Sherman
  • 3,789
  • 1
  • 30
  • 33
Ben Collins
  • 20,538
  • 18
  • 127
  • 187
  • I'm not sure client.OpenRead respects encoding set for webClient instance – chester89 Aug 29 '16 at 12:25
  • A caveat to point out: you must actually _read_ the gzip stream in order for it to uncompress; attempting to be clever with something like `responseStream.CopyTo( File.OpenWrite(...) )` doesn't work – drzaus Sep 13 '16 at 15:07