Windows.Web.Http.HttpClient クラスについて

Windows 8.1 の Windows Runtimeには、新しい HTTP スタックとして Windows.Web.Http 名前空間にHttpClient クラスが追加されています。この HttpClient クラスは、Windows 8.1 の新機能ガイドによれば コネクト スタンバイのリアルタイム通信で利用できるとの説明があります。しかし、使って見ると注意しないといけない点がありました。それは、GetStringAsyncメソッドの使い方です。以下に簡単なサンプルを示します。

 async Task<string> GetContent(string url)
{
  var uri = new Uri(url);
  var client = new HttpClient();
  var data = await client.GetStringAsync(uri);
  return data
}

このGetContentメソッドで戻ってくる文字列ですが、httpヘッダーに「Content-Type: text/html;charset=utf-8」などの文字エンコーディングが指定されている時は期待した文字列が返ります。しかし、「Content-Type : text/xml」のようにcharset指定がないとASCII文字が返ってくるので、文字化けが発生したような状態になります。この問題を回避するには、サーバー側でhttpヘッダーにcharsetを返すようにするか、取得したデータから正しいエンコーディングで処理しないといけません。RSSなどのXMLで簡易的に対処するには、以下のようにします。

 async Task<string> GetContent(string url)
{
  var uri = new Uri(url);
  var client = new HttpClient();
  var content = response.Content;
  var stream = (await content.ReadAsBufferAsync()).AsStream();
  var reader = (TextReader)new StreamReader(stream);
  var data = reader.ReadToEnd();
  return data
}

コードを見れば分りますが、Contentプロパティからストリームを取り出して、TextReaderで読み込むという作業をすることで正しい文字列を取得することができます。もちろん、XMLであればXDocumentにストリームを読み込むなどの方法も考えられます。
もしくは、文字のエンコーディングを知っているのであれば、Encodingクラスを使用してバイト配列から正しいエンコードに変換することもできます。この用途では、「(await content.ReadAsBufferAsync()).ToArray()」のようにToArray拡張メソッドを呼び出すことでバイト配列を取得できるようになります。

使い方さえ間違えなければ、コネクテッド スタンバイのようなシナリオでhttp通信を行うことができるので、新しいHttpClientクラスも有効活用してみましょう。

追記:Content-Typeヘッダーを取得するには、レスポンスのContent.Headersプロパティ経由で取得します。レスポンス メッセージ オブジェクトのHeadersコレクションに含まれていないのでご注意ください。