9

I'm consuming some data using the XML API. This API always offers data as UTF-8.

When using the WebClient class for making a request I am able to set the encoding. For example:

var result = new WebClient(); 
result.Encoding = Encoding.UTF8;

But what about the HttpClient class?

HttpClient client = new HttpClient();

Should I use:

client.GetByteArrayAsync(url);

...and then convert the bytes from the encoding (UTF-8) to a string?

Or is there a way to directly get the content as a UTF-8 string?

using (var client = Connector.GetHttpClient())
{
    var byteData = await client.GetByteArrayAsync(url);
    data = Encoding.UTF8.GetString(byteData);
}

Finally, here is an excerpt from the XML response:

<?xml version="1.0" encoding="UTF-8"?>
<response>
DavidRR
  • 18,291
  • 25
  • 109
  • 191
Boas Enkler
  • 12,264
  • 16
  • 69
  • 143

2 Answers2

11

You should be able to use GetStringAsync - I'd expect the encoding to be determined by the headers in the HTTP response. If the server doesn't specify the encoding, then you should potentially ask for that to be fixed.

Alternatively, if you're fetching XML data, just fetch it as a byte array and parse that binary directly - the XML declaration should specify the encoding for non-UTF-8/UTF-16 data anyway, so I'd argue that actually there's less room for error this way.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • Hi Jon. Thx for your reply. The Encoding Tag is always included the response. In the FogBugz Case it is defined to be always UTF-8. Here an example of the beginning of the XML .... I relied on this with webclient, there the encoding wasn't respected from the api, So i don't feel sure to trust again on the api without the documented feature :-( So Getting the ByteArray (like my codesample above) should be the safest way ? – Boas Enkler Jun 13 '12 at 16:05
  • 1
    @BoasEnkler: The client isn't going to take the encoding from the *body* - it should be specified in the *headers*. But as I've said, the safer way is to fetch it as bytes and parse it just from the binary data. (Create a `MemoryStream` to wrap the byte array.) – Jon Skeet Jun 13 '12 at 16:06
  • ok think thats the best solution. Kris also recommended the same thing :) – Boas Enkler Jun 13 '12 at 16:09
  • Just one more question. When Wrapping the bytes ina memoery and passing it to the XELement.Load. Does this method dispose the memory stream automatically when not needed any more ? Or should I take care of it by myself? – Boas Enkler Jun 13 '12 at 16:20
  • 1
    In theory you should Dispose it. In practice, Dispose does nothing for a MemoryStream (there are no unmanaged resources behind it). – Kris Vandermotten Jun 13 '12 at 16:21
  • May i dispose it direct after load of should it exist as lon as I'm using the created XElement? – Boas Enkler Jun 13 '12 at 16:22
  • @BoasEnkler: What Kris said, basically. You can dispose of it immediately after you've parsed the data from it, if you're just using `XElement.Parse`. If you were to create an `XmlReader` from it, that would be a different matter, as that maintains a reference to the stream, so it can read data only as it needs it. – Jon Skeet Jun 13 '12 at 16:29
5

If I understand correctly, you don't need a string, you need XML.

So, assuming your data is not too big, read a byte array with

byte[] bytes = await client.GetByteArrayAsync(url); 

then create a memory stream from that array, and then read XML from that stream, for example:

XElement element = XElement.Load(new MemoryStream(bytes), LoadOptions.None);

If you're using another XML API, you can use

XmlReader reader = XmlReader.Create(new MemoryStream(bytes));
Kris Vandermotten
  • 10,111
  • 38
  • 49