質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

.NET Framework

.NET Framework は、Microsoft Windowsのオペレーティングシステムのために開発されたソフトウェア開発環境/実行環境です。多くのプログラミング言語をサポートしています。

Xamarin

Xamarin(ザマリン)は、iPhoneなどのiOSやAndroidで動作し、C# 言語を用いてアプリを開発できるクロスプラットフォーム開発環境です。Xamarin Studioと C# 言語を用いて、 iOS と Android の両方の開発を行うことができます。

Q&A

解決済

1回答

5241閲覧

【.NET】【C#】【Xamarin】HttpClient における MultipartFormDataContent

Daiki-Kawanuma

総合スコア29

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

.NET Framework

.NET Framework は、Microsoft Windowsのオペレーティングシステムのために開発されたソフトウェア開発環境/実行環境です。多くのプログラミング言語をサポートしています。

Xamarin

Xamarin(ザマリン)は、iPhoneなどのiOSやAndroidで動作し、C# 言語を用いてアプリを開発できるクロスプラットフォーム開発環境です。Xamarin Studioと C# 言語を用いて、 iOS と Android の両方の開発を行うことができます。

0グッド

0クリップ

投稿2018/03/20 00:55

【実装環境】

  • Xamarin.Forms 2.5.0.122203
  • PCL Profile7
  • Android の HttpClient を使用

 

【やりたいこと】
Xamarin で、HttpClient を用いてマルチパートなデータを送信したいです。
実現したいのは以下のcurlになります。

curl

1curl -v -H "Content-Type:multipart/form-data" 2-F "parameters={\"communityDetail\":\"world\",\"communityName\":\"hello\",\"communityTags\":\"#hello\"};type=application/json" 3-F "file=@/Users/Daiki/Desktop/cat06.jpg" 4https://app-server.mybluemix.net/api/v1/communities

 
【試したコード】
以下のコードを試しました。

C#

1var content = new MultipartFormDataContent(); 2content.Headers.ContentType = MediaTypeHeaderValue.Parse("multipart/form-data"); 3 4var imageContent = new ByteArrayContent(imageByteArray); 5imageContent.Headers.ContentDisposition = 6 new ContentDispositionHeaderValue("form-data") {Name = "\"file\""}; 7imageContent.Headers.ContentType = MediaTypeHeaderValue.Parse("image/jpeg"); 8content.Add(imageContent, "file"); 9 10var bytes = System.Text.Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(community)); 11var byteContent = new ByteArrayContent(bytes); 12byteContent.Headers.ContentDisposition = 13 new ContentDispositionHeaderValue("form-data") {Name = "\"parameters\""}; 14byteContent.Headers.ContentType = new MediaTypeHeaderValue("application/json"); 15content.Add(byteContent, "parameters"); 16 17var response = await _client.PostAsync("api/v1/communities", content); 18Debug.WriteLine(response.StatusCode + ", " + response.Content.ReadAsStringAsync().Result);

結果、以下のレスポンスが返っています(サーバーサイドは Spring Boot)。

InternalServerError, {"timestamp":1521470466137,"status":500,"error":"Internal Server Error","exception":"org.springframework.web.multipart.MultipartException","message":"Could not parse multipart servlet request; nested exception is java.io.IOException: org.apache.tomcat.util.http.fileupload.FileUploadException: the request was rejected because no multipart boundary was found","path":"/api/v1/communities"}

 
マルチパートなデータが正しく送れていないように見えますが、何か間違っているところがありますでしょうか?
ご教授のほど、よろしくお願い致します。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

ちょろっと試してみましたが、サンプルのコードは全体的におかしいです。

  • 方やMediaTypeHeaderValue.Parse("multipart/form-data")の記述、

方やnew MediaTypeHeaderValue("application/json")の記述、統一されてないのが気になる

  • インスタンスをJson化してByteArrayContentとして宣言しているのはいいが、その場合MediaTypeHeaderValueはJsonではなくなるのでは?

Jsonを指定するならByteArrayContentではなくStringContentを使うのが適当

  • ✕:ご教授

◯:ご教示

とりあえずローカルでWebAPI立てて送受信テストしてみましたが、これでHTTP.OKになります。

C#

1 static async Task Send() 2 { 3 var imageByteArray = File.ReadAllBytes(@"C:\work\image.png"); 4 var community = new { Key = "Test", Name = "Hoge", Desc = "Fuga" }; 5 using (var _client = new HttpClient()) 6 { 7 var content = new MultipartFormDataContent(); 8 //content.Headers.ContentType = MediaTypeHeaderValue.Parse("multipart/form-data"); 9 10 var imageContent = new ByteArrayContent(imageByteArray); 11 //imageContent.Headers.ContentDisposition = new ContentDispositionHeaderValue("form-data") { Name = "\"file\"" }; 12 //imageContent.Headers.ContentType = MediaTypeHeaderValue.Parse("image/jpeg"); 13 imageContent.Headers.ContentType = new MediaTypeHeaderValue("image/jpeg"); 14 content.Add(imageContent, "file"); 15 16 var bytes = System.Text.Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(community)); 17 var byteContent = new ByteArrayContent(bytes); 18 //byteContent.Headers.ContentDisposition = new ContentDispositionHeaderValue("form-data") { Name = "\"parameters\"" }; 19 //byteContent.Headers.ContentType = new MediaTypeHeaderValue("application/json"); 20 content.Add(byteContent, "parameters"); 21 22 var response = await _client.PostAsync("http://localhost:25980/api/values", content); 23 Debug.WriteLine(response.StatusCode + ", " + response.Content.ReadAsStringAsync().Result); 24 } 25 }

あとは余談ですが、HttpClientはAndroidのものではなく.NET標準です。
なのでタグにあるXamarinも不適当で、たたただ単純にHTTP送信ができないってのが困りごとの本質です。

投稿2018/03/20 01:34

ShikaTech

総合スコア468

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Daiki-Kawanuma

2018/03/20 13:47

ご回答いただきましてありがとうございます。 理解不足で統一感のないコード、言葉の誤用失礼しました。 ご回答いただきました内容を元に修正したところ、サーバー側から 200 OK を得ることができました。 Spring Boot の制約なのか、content.Add(imageContent, "file", "test.jpg"); のようにファイル名を追加しないとエラーになるようです。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問