kazuakix の日記

Windows Phone とか好きです

HttpClient がふたつ?

本当に久しぶりにコード書いてて浦島太郎状態なんですが、いつの間にか HttpClinet がふたつに増えてました。

f:id:kazuakix:20140517233343j:plain

で、使い慣れた System.Net.Http.HttpClient にはこんな注釈が...

注  System.Net.Http 名前空間と System.Net.Http.Headers 名前空間は、Windows の将来のバージョンでは Windows ストア アプリ用に使用できないことがあります。Windows 8.1 および Windows Server 2012 R2 以降、Windows ランタイム アプリでは代わりに、Windows.Web.Http 名前空間Windows.Web.Http.HttpClient と、関連する Windows.Web.Http.Headers 名前空間および Windows.Web.Http.Filters 名前空間を使います。


それなら新しい方使えばいいよね。って思ったのですが注意点もあるようです。


「Content-Type : text/xml」のようにcharset指定がないとASCII文字が返ってくるので、文字化けが発生したような状態になります。この問題を回避するには、サーバー側でhttpヘッダーにcharsetを返すようにするか、取得したデータから正しいエンコーディングで処理しないといけません。


使い方も地味~に違ってます。
System.Net.Http のつもりでこんな感じで書きかけたのですが、

var req = new HttpClient();
var res = await req.GetAsync(uri);
if (res.IsSuccessStatusCode)
{
    var folder = await Windows.Storage.KnownFolders.PicturesLibrary.CreateFolderAsync("FlashAir", CreationCollisionOption.OpenIfExists);
    if (null == folder) return false;
    var file = await folder.CreateFileAsync(FileName, CreationCollisionOption.ReplaceExisting);

    using (var src = await res.Content.ReadAsStreamAsync())
    using (var dst = await file.OpenStreamForWriteAsync())
    {
        byte[] buffer = new byte[src.Length];
        src.Read(buffer,  0, (int)src.Length);
        dst.Write(buffer, 0, (int)src.Length);
    }

    return true;
}

こんな感じでしょうか?

    using (var src = (await res.Content.ReadAsInputStreamAsync()).AsStreamForRead())
    using (var dst =  await file.OpenStreamForWriteAsync())
    {
        byte[] buffer = new byte[(int)res.Content.Headers.ContentLength];
        src.Read(buffer,  0, (int)res.Content.Headers.ContentLength);
        dst.Write(buffer, 0, (int)res.Content.Headers.ContentLength);
    }

HttpResponseMessage.Content が HttpContent から IHttpContent になってるからなのか ReadAsStreamAsync がありませんでした。ReadAsInputStreamAsync したものを AsStreamForRead ... ってなんか面倒になってますね。

他にも取得した stream に Length プロパティがなかったので レスポンス ヘッダ の ContentLength を見るようにしました。

これで遅いようなら System.Net.Http に戻すと思います。