概要
- 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を使用してフォーム(キー=値)を送信できます。
var 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要求のイメージは次の通りです。
POST /api/DummyApi?body=image HTTP/1.1 traceparent: 00-96ba339be5710a0462fbb31c69de18af-917ffcc4b4fd5f1b-00 Content-Type: application/x-www-form-urlencoded Content-Length: 33 key1=%E5%80%A4%EF%BC%91&key2=1234
テキストのPOST
- StringContentを使用してテキストを送信できます。
コンテンツ内容としてJSON文字列、コンテンツタイプとして”text/json”を指定してJSONを送信することもできます。コンテンツタイプに関して、主要なものはmdn、完全なものはIANAをご覧ください。var 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要求のイメージは次の通りです。
POST /api/DummyApi?body=json HTTP/1.1 traceparent: 00-808d7e9be49a229396da905b157a4155-312f6aa1d6bf94f0-00 Content-Type: text/plain; charset=utf-8 Content-Length: 22 key1=......, key2=1234
JSONのPOST
- JsonContentを使用して、C#のオブジェクトから変換したJSONを送信できます。
JsonSerializerでJSON文字列を生成し、前述のようにStringContentで送信することもできます。
コンテンツタイプに関して、主要なものはmdn、完全なものはIANAをご覧ください。var 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要求のイメージは次の通りです。
POST /api/DummyApi?body=json HTTP/1.1 Transfer-Encoding: chunked traceparent: 00-887f351c976ccd61fc2153caf25bab66-ffedd1bd14c4b825-00 Content-Type: application/json; charset=utf-8 {"key1":"\u5024\uFF11","key2":1234}
画像等のバイナリのPOST
- バイト配列のコンテンツの場合、ByteArrayContentを使用して送信できます。
必要に応じてコンテンツタイプを指定します。コンテンツタイプに関して、主要なものはmdn、完全なものはIANAをご覧ください。var 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を使用して送信できます。
var 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要求のイメージは次の通りです。
POST /api/DummyApi HTTP/1.1 traceparent: 00-ae4b8ae4734f23d6817ed12b22a256dc-f8103d3e7300c460-00 Content-Type: image/png Content-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をご覧ください。var 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の値に引用符がない場合があり、一部のシステムではエラーになる場合があります。詳細はこちらをご覧ください。POST /api/DummyApi?body=json HTTP/1.1 traceparent: 00-702d4c28ac18059b523d842fba5a6dc3-da082db5550978aa-00 Content-Type: multipart/form-data; boundary="b702b5c5-ebc3-4149-8f55-25664e56f329" Content-Length: 1605 --b702b5c5-ebc3-4149-8f55-25664e56f329 Content-Type: text/plain; charset=utf-8 Content-Disposition: form-data; name=key1 ...... --b702b5c5-ebc3-4149-8f55-25664e56f329 Content-Type: image/png Content-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-25664e56f329 Content-Type: image/jpeg Content-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--
