如何使用 HttpClient 发布表单数据 IFormFile?

Dei*_*kis 18 c# post http multipartform-data asp.net-core

我有后端端点Task<ActionResult> Post(IFormFile csvFile),我需要从 HttpClient 调用这个端点。目前我得到Unsupported media type error. 这是我的代码:

var filePath = Path.Combine("IntegrationTests", "file.csv");
var gg = File.ReadAllBytes(filePath);
var byteArrayContent = new ByteArrayContent(gg);
var postResponse = await _client.PostAsync("offers", new MultipartFormDataContent
{
    {byteArrayContent }
});
Run Code Online (Sandbox Code Playgroud)

Ale*_*der 22

您需要在MultipartFormDataContent集合中指定参数名称匹配动作参数名称 ( csvFile) 和一个随机文件名

var multipartContent = new MultipartFormDataContent();
multipartContent.Add(byteArrayContent, "csvFile", "filename");
var postResponse = await _client.PostAsync("offers", multipartContent);
Run Code Online (Sandbox Code Playgroud)

或同等学历

var postResponse = await _client.PostAsync("offers", new MultipartFormDataContent {
    { byteArrayContent, "csvFile", "filename" }
});
Run Code Online (Sandbox Code Playgroud)

  • 如果我的类型不是“IFormFile”,而是“List&lt;IFormFile&gt;”怎么办?谢谢。 (3认同)

Moi*_*jik 7

使用这个片段:

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);
                }
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 3/5 的 using 语句可以简化为一行 `var fileContent = new ByteArrayContent(await File.ReadAllBytesAsync(filePath));` (3认同)

小智 6

这对我来说是通用的

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);
    }
Run Code Online (Sandbox Code Playgroud)