How to post form-data IFormFile with HttpClient?
Use this snippet:
const string url = "https://localhost:5001/api/Upload";
const string filePath = @"C:\Path\To\File.png";
using (var httpClient = new HttpClient())
{
using (var form = new MultipartFormDataContent())
{
using (var fs = File.OpenRead(filePath))
{
using (var streamContent = new StreamContent(fs))
{
using (var fileContent = new ByteArrayContent(await streamContent.ReadAsByteArrayAsync()))
{
fileContent.Headers.ContentType = MediaTypeHeaderValue.Parse("multipart/form-data");
// "file" parameter name should be the same as the server side input parameter name
form.Add(fileContent, "file", Path.GetFileName(filePath));
HttpResponseMessage response = await httpClient.PostAsync(url, form);
}
}
}
}
}
Solved by using this code:
const string fileName = "csvFile.csv";
var filePath = Path.Combine("IntegrationTests", fileName);
var bytes = File.ReadAllBytes(filePath);
var form = new MultipartFormDataContent();
var content = new StreamContent(new MemoryStream(bytes));
form.Add(content, "csvFile");
content.Headers.ContentDisposition = new ContentDispositionHeaderValue("form-data")
{
Name = "csvFile",
FileName = fileName
};
content.Headers.Remove("Content-Type");
content.Headers.Add("Content-Type", "application/octet-stream; boundary=----WebKitFormBoundaryMRxYYlVt8KWT8TU3");
form.Add(content);
//Act
var postResponse = await _sellerClient.PostAsync("items/upload", form);
This worked for me as a generic
public static Task<HttpResponseMessage> PostFormDataAsync<T>(this HttpClient httpClient, string url, string token, T data)
{
var content = new MultipartFormDataContent();
foreach (var prop in data.GetType().GetProperties())
{
var value = prop.GetValue(data);
if (value is FormFile)
{
var file = value as FormFile;
content.Add(new StreamContent(file.OpenReadStream()), prop.Name, file.FileName);
content.Headers.ContentDisposition = new ContentDispositionHeaderValue("form-data") { Name = prop.Name, FileName = file.FileName };
}
else
{
content.Add(new StringContent(JsonConvert.SerializeObject(value)), prop.Name);
}
}
if (!string.IsNullOrWhiteSpace(token))
httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
return httpClient.PostAsync(url, content);
}
You need to specify parameter name in MultipartFormDataContent
collection matching action parameter name (csvFile
) and a random file name
var multipartContent = new MultipartFormDataContent();
multipartContent.Add(byteArrayContent, "csvFile", "filename");
var postResponse = await _client.PostAsync("offers", multipartContent);
or equivalent
var postResponse = await _client.PostAsync("offers", new MultipartFormDataContent {
{ byteArrayContent, "csvFile", "filename" }
});