Home > Enterprise >  HTTP POST multipart/formdata using HttpClient
HTTP POST multipart/formdata using HttpClient

Time:07-05

When I post the below code using httpclient

using var formContent = new MultipartFormDataContent("NKdKd9Yk");
using var stream = new MemoryStream();
file.CopyTo(stream);
var fileBytes = stream.ToArray();
formContent.Headers.ContentType.MediaType = "multipart/form-data";
formContent.Add(new StreamContent(stream), "file", fileName);
var response = await httpClient.PostAsync(GetDocumentUpdateRelativeUrl(), formContent);

here file is of type IFormfile

In API side I retrieve file as follows

var base64str= "";
using (var ms = new MemoryStream())
{
    request.file.CopyTo(ms);
    var fileBytes = ms.ToArray();
    base64str= Convert.ToBase64String(fileBytes);
    // act on the Base64 data
}

I get 0 byte. My questions is what's wrong with this approch?

But If I use below code. Then API works and I get what I post.

using var formContent = new MultipartFormDataContent("NKdKd9Yk");
using var stream = new MemoryStream();
file.CopyTo(stream);
var fileBytes = stream.ToArray();
formContent.Headers.ContentType.MediaType = "multipart/form-data";
formContent.Add(new StreamContent(new MemoryStream(fileBytes)), "file", fileName);

differece is how I add stream content

formContent.Add(new StreamContent(stream), "file", fileName);
vs
formContent.Add(new StreamContent(new MemoryStream(fileBytes)), "file", fileName);

Why the first approch didn't work but second one does?

CodePudding user response:

You need to add stream.Seek(0, SeekOrigin.Begin); in order to jump back to the beginning of the MemoryStream. You should also use CopyToAsync

In the second version, you had a fresh MemoryStream from the byte[] array, which is positioned on 0 anyway.

using var formContent = new MultipartFormDataContent("NKdKd9Yk");
using var stream = new MemoryStream();
await file.CopyToAsync(stream);
stream.Seek(0, SeekOrigin.Begin);
formContent.Headers.ContentType.MediaType = "multipart/form-data";
formContent.Add(new StreamContent(stream), "file", fileName);
using var response = await httpClient.PostAsync(GetDocumentUpdateRelativeUrl(), formContent);

Although to be honest, the MemoryStream seems entirely unnecessary here. Just pass the a Stream from file directly.

using var formContent = new MultipartFormDataContent("NKdKd9Yk");
formContent.Headers.ContentType.MediaType = "multipart/form-data";
using var stream = file.OpenReadStream();
formContent.Add(new StreamContent(stream), "file", fileName);
using var response = await httpClient.PostAsync(GetDocumentUpdateRelativeUrl(), formContent);

  • Related