ぷろじぇくと、みすじら。

HttpClient の StringContent は charset を付ける

Created at:

tl;dr

はじまり

HttpClient でとある API (POST) を呼び出すとなぜか動かない… curl で同じ内容を投げると動くのに…という相談を受けて、そんな不思議なことが?と思って調べてみたのが始まりでした。

.NET の HttpClient, StringContent は自動で charset を付ける

curl で動いているなら .NET の HttpClient が投げるものが何か違うのではと思って、リクエストやリクエストを作っているところを確認してみました。

https://github.com/dotnet/corefx/blob/dbf74fac15dad697ae7e7c4d88327c0478f465ef/src/System.Net.Http/src/System/Net/Http/StringContent.cs#L30-L34

// Initialize the 'Content-Type' header with information provided by parameters.
MediaTypeHeaderValue headerValue = new MediaTypeHeaderValue((mediaType == null) ? DefaultMediaType : mediaType);
headerValue.CharSet = (encoding == null) ? HttpContent.DefaultStringEncoding.WebName : encoding.WebName;

Headers.ContentType = headerValue;

StringContent クラスのコンストラクターのコードではメディアタイプとともに CharSet プロパティを設定したものをヘッダーの ContentType プロパティに設定しています。この CharSet プロパティは Content-Type の charset 指定になります。

つまり StringContent クラスを使って投げるリクエストを作るとデフォルトで application/json; charset=utf-8 のような Content-Type で送られるということになります。

ContentType を再設定する

charset パラメータが必ずついてしまうということが分かったので、付けずにリクエストを送信したいという場合にはこれを変える必要があります。

といってもやることは簡単で後から手動で ContentType プロパティを再設定してあげれば大丈夫です。

content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/json");