概要
- HttpClientを使用して、テキスト、JSON、画像、マルチパートのコンテンツをHTTPで送信するサンプルを紹介します。
- 使用環境は次の通りです。
OS Windows 10(64ビット) IDE Microsoft Visual Studio Community 2022(17.6.0) 言語 C#(10.0) + .NET6
サンプル
- サンプルはgithubで公開しています。
- ASP.NET(.NET6)では、IHttpClientFactoryから取得したHttpClientの使用が推奨されてるので、その想定の例になっています。詳細はリファレンスをご覧ください。
- HTTP要求のイメージは、こちらで紹介している仕組みで文字列にダンプしています。
(Hostヘッダは含まれていません。日本語を含む非印刷可能文字は.
になっており、本稿では適当に間引いています。)
フォームのPOST
- FormUrlEncodedContentを使用してフォーム(キー=値)を送信できます。12345678910111213141516var targetUri = new Uri("https://...");var forms = new Dictionary<string, string>(){{"key1", "値1" }, { "key2", "1234"}};using var content = new FormUrlEncodedContent(forms); // "application/x-www-form-urlencoded"using var req = new HttpRequestMessage(){Method = HttpMethod.Post,RequestUri = targetUri,Content = content};var httpClient = _httpClientFactory.CreateClient();using var res = await httpClient.SendAsync(req);
- 生成されるHTTP要求のイメージは次の通りです。123456POST /api/DummyApi?body=image HTTP/1.1traceparent: 00-96ba339be5710a0462fbb31c69de18af-917ffcc4b4fd5f1b-00Content-Type: application/x-www-form-urlencodedContent-Length: 33key1=%E5%80%A4%EF%BC%91&key2=1234
テキストのPOST
- StringContentを使用してテキストを送信できます。
コンテンツ内容としてJSON文字列、コンテンツタイプとして”text/json”を指定してJSONを送信することもできます。コンテンツタイプに関して、主要なものはmdn、完全なものはIANAをご覧ください。12345678910111213var targetUri = new Uri("https://...");var data = "key1=値1, key2=1234";using var content = new StringContent(data); // "text/plain; charset=utf-8"using var req = new HttpRequestMessage(){Method = HttpMethod.Post,RequestUri = targetUri,Content = content};var httpClient = _httpClientFactory.CreateClient();using var res = await httpClient.SendAsync(req); - 生成されるHTTP要求のイメージは次の通りです。123456POST /api/DummyApi?body=json HTTP/1.1traceparent: 00-808d7e9be49a229396da905b157a4155-312f6aa1d6bf94f0-00Content-Type: text/plain; charset=utf-8Content-Length: 22key1=......, key2=1234
JSONのPOST
- JsonContentを使用して、C#のオブジェクトから変換したJSONを送信できます。
JsonSerializerでJSON文字列を生成し、前述のようにStringContentで送信することもできます。
コンテンツタイプに関して、主要なものはmdn、完全なものはIANAをご覧ください。123456789101112131415var targetUri = new Uri("https://...");var data = new Dictionary<string, object>() {{"key1", "値1" }, {"key2", 1234}};using var content = JsonContent.Create(data); // "application/json; charset=utf-8"using var req = new HttpRequestMessage(){Method = HttpMethod.Post,RequestUri = targetUri,Content = content};var httpClient = _httpClientFactory.CreateClient();using var res = await httpClient.SendAsync(req); - 生成されるHTTP要求のイメージは次の通りです。123456POST /api/DummyApi?body=json HTTP/1.1Transfer-Encoding: chunkedtraceparent: 00-887f351c976ccd61fc2153caf25bab66-ffedd1bd14c4b825-00Content-Type: application/json; charset=utf-8{"key1":"\u5024\uFF11","key2":1234}
画像等のバイナリのPOST
- バイト配列のコンテンツの場合、ByteArrayContentを使用して送信できます。
必要に応じてコンテンツタイプを指定します。コンテンツタイプに関して、主要なものはmdn、完全なものはIANAをご覧ください。12345678910111213var targetUri = new Uri("https://...");using var content = new ByteArrayContent(_image1bytes);content.Headers.ContentType = new MediaTypeHeaderValue("image/png");using var req = new HttpRequestMessage(){Method = HttpMethod.Post,RequestUri = targetUri,Content = content};var httpClient = _httpClientFactory.CreateClient();using var res = await httpClient.SendAsync(req); - ストリームのコンテンツの場合、StreamContentを使用して送信できます。1234567891011121314var targetUri = new Uri("https://...");using var stream = new MemoryStream(_image2bytes);using var content = new StreamContent(stream);content.Headers.ContentType = new MediaTypeHeaderValue("image/png");using var req = new HttpRequestMessage(){Method = HttpMethod.Post,RequestUri = targetUri,Content = content};var httpClient = _httpClientFactory.CreateClient();using var res = await httpClient.SendAsync(req);
- 生成されるHTTP要求のイメージは次の通りです。12345678910POST /api/DummyApi HTTP/1.1traceparent: 00-ae4b8ae4734f23d6817ed12b22a256dc-f8103d3e7300c460-00Content-Type: image/pngContent-Length: 233.PNG....IHDR...@...@......iq.....sRGB.........gAMA......a.......o...j..j..j..j..j..j..j..j..j..j..j..j..j..j..j..j.
マルチパートのPOST
- MultipartFormDataContentを使用して、マルチパートのデータを送信できます。
マルチパートには、前述のStringContent, StreamContent等のクラスを使用して様々なコンテンツを追加できます。
コンテンツタイプに関して、主要なものはmdn、完全なものはIANAをご覧ください。12345678910111213141516171819202122var targetUri = new Uri("https://...");using var part1 = new StringContent("値1");using var part2 = new ByteArrayContent(_image1bytes);part2.Headers.ContentType = new MediaTypeHeaderValue("image/png");using var part3 = new ByteArrayContent(_image2bytes);part3.Headers.ContentType = new MediaTypeHeaderValue("image/jpeg");using var multipartContent = new MultipartFormDataContent{{ part1, "key1" },{ part2, "key2", "sample1.png" },{ part3, "key3", "サンプル2.jpg" }};using var req = new HttpRequestMessage(){Method = HttpMethod.Post,RequestUri = targetUri,Content = multipartContent};var httpClient = _httpClientFactory.CreateClient();using var res = await httpClient.SendAsync(req); - 生成されるHTTP要求のイメージは次の通りです。
Content-Dispositionでファイル名を指定する場合、13行目のようにfilenameの値に引用符がない場合があり、一部のシステムではエラーになる場合があります。詳細はこちらをご覧ください。1234567891011121314151617181920212223242526POST /api/DummyApi?body=json HTTP/1.1traceparent: 00-702d4c28ac18059b523d842fba5a6dc3-da082db5550978aa-00Content-Type: multipart/form-data; boundary="b702b5c5-ebc3-4149-8f55-25664e56f329"Content-Length: 1605--b702b5c5-ebc3-4149-8f55-25664e56f329Content-Type: text/plain; charset=utf-8Content-Disposition: form-data; name=key1......--b702b5c5-ebc3-4149-8f55-25664e56f329Content-Type: image/pngContent-Disposition: form-data; name=key2; filename=sample1.png; filename*=utf-8''sample1.png.PNG....o...j..j..j..j..j..j..j..j..j..j..j..j..j....j..j..j..j..j....Y...........IEND.B`.--b702b5c5-ebc3-4149-8f55-25664e56f329Content-Type: image/jpegContent-Disposition: form-data; name=key3; filename="=?utf-8?B?44K144Oz44OX44Or77ySLmpwZw==?="; filename*=utf-8''%E3%82%B5%E3%83%B3%E3%83%97%E3%83%AB%EF%BC%92.jpg......JFIF.....`.`.....fExif..MM.*......................................}........!1A..Qa."q.2....#B...R..$3br.......%&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz.......................?..z(..x?...(...(...(...(...(...(...(...(...(...(...(...(...(...(...(....--b702b5c5-ebc3-4149-8f55-25664e56f329--