備忘録

備忘録

C# HttpClientでContent-Typeを指定する方法

Ⅰ. はじめに

基本的にはHttpContentを継承したクラス(FormUrlEncodedContentなど)があるのでそれを使います。
しかし、なんとかしてContent-Typeを任意の値に変更したい場合は以下のように書きます。

Ⅱ. 文字列の場合

using(var client = new HttpClient())
{
  var content = new StringContent("this is content", new UTF8Encoding(), "application/x-www-form-urlencoded");
  await client.PostAsync("http://hoge.com", content);
}

実際に送信される生のリクエス

POST http://hoge.com/ HTTP/1.1
Content-Type: application/x-www-form-urlencoded; charset=utf-8
Host: hoge.com
Content-Length: 15
Expect: 100-continue
Connection: Keep-Alive

this is content

Ⅲ. バイト配列の場合

方法1
using(var client = new HttpClient())
{
  var content = new ByteArrayContent(new byte[] { (byte)'a', (byte)'b', (byte)'c' });
  content.Headers.ContentType = new MediaTypeHeaderValue("application/x-www-form-urlencoded");
  await client.PostAsync("http://hoge.com", content);
}
方法2
using(var client = new HttpClient())
{
  var req = new HttpRequestMessage();
  req.RequestUri = new Uri("http://hoge.com");
  req.Method = HttpMethod.Post;
  req.Content = new ByteArrayContent(new byte[] { (byte)'a', (byte)'b', (byte)'c' });
  req.Content.Headers.Add("Content-Type", "application/x-www-form-urlencoded");

  await client.SendAsync(req);
}

実際に送信される生のリクエス

POST http://hoge.com/ HTTP/1.1
Content-Type: application/x-www-form-urlencoded
Host: hoge.com
Content-Length: 3
Expect: 100-continue
Connection: Keep-Alive

abc

※Expect: 100-continueは以下の1行を書いておくと無効になります

ServicePointManager.Expect100Continue = false;

Ⅳ. ダメな例

以下のようなエラーが出ます

ハンドルされていない例外: System.AggregateException: 1 つ以上のエラーが発生しました。
---> System.InvalidOperationException: ヘッダー名に誤用があります。
要求ヘッダーと HttpRequestMessage 、応答ヘッダーと HttpResponseMessage、
コンテンツ ヘッダーと HttpContent オブジェクトとを組み合わせて使用していることを確認してください。
using (var client = new HttpClient())
{
  client.DefaultRequestHeaders.Add("Content-Type", "application/x-www-form-urlencoded");
  await client.PostAsync("http://hoge.com", new StringContent("content"));
}