web-dev-qa-db-ja.com

補修付きマルチパートコンテンツ

Refitでマルチパートを使用しています。私のサービスのプロフィール写真をアップロードしようとしましたが、郵便配達員から生成されたコードは次のようになっています

var client = new RestClient("http://api.example.com/api/users/1");
var request = new RestRequest(Method.POST);
request.AddHeader("Postman-Token", "xxx");
request.AddHeader("Cache-Control", "no-cache");
request.AddHeader("content-type", "multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW");
request.AddParameter("multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW", "------WebKitFormBoundary7MA4YWxkTrZu0gW\r\nContent-Disposition: form-data; name=\"_method\"\r\n\r\nput\r\n------WebKitFormBoundary7MA4YWxkTrZu0gW\r\nContent-Disposition: form-data; name=\"profile_picture\"; filename=\"ic_default_avatar.png\"\r\nContent-Type: image/png\r\n\r\n\r\n------WebKitFormBoundary7MA4YWxkTrZu0gW--", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);

そして、私はこのようにRefitメソッドを構築します

[Multipart]
[Post("/users/{id}")]
IObservable<BaseResponse<User>> UpdateProfilePicture(int id,[AliasAs("profile_picture")] byte[] profilePicture,[AliasAs("_method")]string method="put");

byte[]またはByteArrayPartを使用すると、例外がスローされます

{System.Net.Http.HttpRequestException:リクエストの送信中にエラーが発生しました---> System.Net.WebException:応答ストリームの取得エラー(チャンクされたRead2):ReceiveFailure ---> System.Exception:at System.Net.WebConnection .HandleError(System.Net.WebExceptionStatus st、System.Exception e、System.String where)[0x00031] in:0 at System.Net.WebConnection.Read(System.Net.HttpWebRequest request、System.Byte [] buffer、System .Int32オフセット、System.Int32サイズ)[0x000d2]の0でSystem.Net.WebConnectionStream.ReadAll()[0x0010e]の0でSystem.Net.HttpWebResponse.ReadAll()[0x00011]の:0でシステム。 Net.HttpWebRequest.CheckFinalStatus(System.Net.WebAsyncResult result)[0x001d6] in:0 at System.Net.HttpWebRequest.SetResponseData(System.Net.WebConnectionData data)[0x0013e] at:0 in System.Net.WebConnection.ReadDone( System.IAsyncResultの結果)[0x0024d]の0でSystem.Net.Sockets.SocketAsyncResult + <> c.b__27_0(System.Object状態)[0x00000]の:0でSystem.Threading.QueueUserWorkItemCa llback.System.Threading.IThreadPoolWorkItem.ExecuteWorkItem()[0x00015]の0でSystem.Threading.ThreadPoolWorkQueue.Dispatch()[0x00074]の:0でObjCRuntime.Runtime.ThreadPoolDispatcher(System.Func`1 [TResult]コールバック) [0x00006] in <0b60c1467e7449608ac42f9c7bbfdd05>:0 at System.Threading._ThreadPoolWaitCallback.PerformWaitCallback()[0x00009] in:0 at System.Net.WebConnection.HandleError(System.Net.WebExceptionStatus st、System.Exception e、System.String where )/Library/Frameworks/Xamarin.iOS.framework/Versions/11.12.0.4/src/Xamarin.iOS/mcs/class/System/System.Net/WebConnection.cs:439の[0x00031]

StreamまたはStreamPartを使用すると、ストリームが閉じているという例外もスローされます。

11
albilaga

IEnumerable<StreamPart>を使用してファイルをアップロードできます。

  [Multipart]
  [Post("/users/{id}")]
  Task UpdateProfilePicture(int id, [AliasAs("profile_picture")] IEnumerable<StreamPart> streams);
8
Hossein

これは古い質問ですが、他の人の役に立つかもしれません。

サーバー側で受信したファイルサイズが常に0だったため、StreamPartも使用できなかったため、ここで指定したようにByteArrayPartを使用しました github.com/reactiveui/refit #multipart-uploads

インターフェース:

[Multipart]
[Post("/api/<some-path>")]
Task<HttpResponseMessage> Upload([AliasAs("file")] ByteArrayPart bytes);

用途:

var stream;
using (MemoryStream ms = new MemoryStream())
{
    stream.CopyTo(ms);
    client.Upload(new ByteArrayPart(ms.ToArray(), fileName));
}

この手法はストリーム全体をメモリにロードすることに注意してください!小さなファイルがあったため、私にとってはうまくいきましたが、大きなファイルを処理しているか、メモリ使用量が問題です。

2
Maxime Gélinas