You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用HttpClient发送Multipart数据调用FromForm接口报400错误求助

问题描述

我有一个接收表单数据的API:

[HttpPost]
[Route("sign")]
public async Task<IActionResult> SignDocument([FromForm] SignDTO signDTO)

SignDTO定义如下:

public class SignDTO
{
    public IFormFile[] Files { get; set; }
    public string CertIdentifier { get; set; }
    public string Certificate { get; set; }
    public string PhoneNumber { get; set; }
    public string UserId { get; set; }
}

我尝试通过以下代码调用该API:

SignDTO request = new SignDTO();
request.UserId = dto.UserId;
request.PhoneNumber = dto.Phone;
request.Certificate = certificate.Value;
request.CertIdentifier = certificate.Key;

HttpClient client = new HttpClient();
client.BaseAddress = new Uri(_signUrl);

var multipartContent = new MultipartFormDataContent();
ByteArrayContent fileContent = new ByteArrayContent(file);
multipartContent.Add(fileContent, "files", "files");
multipartContent.Add(new StringContent(JsonConvert.SerializeObject(request), Encoding.UTF8, "application/json"), "signDTO");
var response = await client.PostAsync("api/sign/sign", multipartContent);

但请求返回400错误,之前用HttpWebRequest实现过类似功能,不确定当前HttpClient的写法是否正确,请问哪里出错了?


问题分析与解决
  • 核心错误:你把整个SignDTO序列化为JSON字符串放到signDTO表单字段中,但API用[FromForm]标记,期望的是表单键值对对应DTO的每个属性,而非序列化后的JSON对象。ASP.NET Core无法将这个JSON字符串自动绑定到SignDTO,因此返回400参数错误。

  • 正确做法:将SignDTO中的每个字符串属性单独作为表单字段添加,同时正确处理文件上传(多文件需循环添加)。

修正后的代码示例:

// 提取参数值
var userId = dto.UserId;
var phoneNumber = dto.Phone;
var certificateVal = certificate.Value;
var certIdentifier = certificate.Key;

HttpClient client = new HttpClient();
client.BaseAddress = new Uri(_signUrl);

var multipartContent = new MultipartFormDataContent();

// 添加文件(多文件的话循环调用Add即可)
ByteArrayContent fileContent = new ByteArrayContent(file);
// 键名"files"需和DTO的Files属性名一致,框架会自动绑定为数组
multipartContent.Add(fileContent, "files", "actual-filename.ext");

// 逐个添加字符串属性,键名必须和DTO属性名完全匹配(大小写敏感)
multipartContent.Add(new StringContent(userId), "UserId");
multipartContent.Add(new StringContent(phoneNumber), "PhoneNumber");
multipartContent.Add(new StringContent(certificateVal), "Certificate");
multipartContent.Add(new StringContent(certIdentifier), "CertIdentifier");

var response = await client.PostAsync("api/sign/sign", multipartContent);

补充说明:

  1. 表单字段的键名必须和SignDTO的属性名完全一致,ASP.NET Core的模型绑定才能正确识别。
  2. 多文件上传时,只需循环调用multipartContent.Add,每个文件都用"files"作为键名,框架会自动收集为IFormFile[]数组。
  3. 无需创建SignDTO对象并序列化,直接将每个字段单独添加到表单即可。

内容的提问来源于stack exchange,提问作者Jamil

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.14 17:40:17