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

如何从React向ASP.NET Core API发送带文件的表单数据

问题根因

你试遍所有组合都拿不到值,核心是踩了三个高频错误:

  1. 手动给FormData请求设置Content-Type头,导致浏览器丢失自动生成的boundary分隔符,后端无法解析表单边界
  2. 后端绑定特性和请求格式不匹配:用[FromBody]接收FormData数据,而[FromBody]仅负责反序列化JSON/XML格式的请求体
  3. 前后端字段命名不匹配、请求头和请求体格式错配

正确实现步骤

先调通普通表单字段传输,再追加文件字段即可,不需要用URLSearchParams、手动拼接urlencoded这类不支持文件传输的格式。

前端(React + fetch)实现

核心规则:使用FormData时绝对不要手动设置Content-Type请求头,浏览器会自动补全带boundary参数的合法multipart/form-data头

// 请求体字段名建议和后端C#类属性名保持一致,避免绑定失败
const reqBody = {
  Username: "user",
  Password: "pass"
};
const formData = new FormData();
// 追加普通表单字段
Object.entries(reqBody).forEach(([key, value]) => {
  formData.append(key, value);
});
// 后续需要传文件时,直接追加文件对象即可(file是input[type=file]选中的文件实例)
// formData.append("UploadFile", file);

fetch("localhost/api/test/login", {
  method: "POST",
  headers: {
    "Accept": "application/json"
    // 不要在这里写Content-Type!不要写!
  },
  body: formData
})
.then(res => res.json())
.then(result => console.log(result));

可以用浏览器F12网络面板验证前端格式是否正确:查看请求的Payload标签,能看到所有FormData字段,且请求头里的Content-Type自带boundary=----WebKitFormBoundaryxxxx后缀,就说明前端格式合法。

后端(ASP.NET Core)实现

核心规则:接收multipart/form-data格式的请求,必须用[FromForm]特性做模型绑定,不能用[FromBody]
接口代码修改如下:

[HttpPost]
[Route("login")]
public IActionResult Login([FromForm] Credentials cred)
{
    // 断点打在这里即可正常获取Username、Password的值
    // 后续接收文件直接从cred.UploadFile取值即可
    return Ok(CustomResult.Ok);
}

参数绑定的实体类如果需要支持文件,直接新增IFormFile类型属性,保证属性名和前端append的字段名完全一致即可:

public class Credentials
{
    public string Username { get; set; }
    public string Password { get; set; }
    // 对应前端append的UploadFile字段
    public IFormFile UploadFile { get; set; }
}

之前尝试的方案为什么失败
  • 手动设置Content-Type: multipart/formdata:首先拼写错误(正确为multipart/form-data),就算拼写正确,缺少浏览器自动生成的boundary参数,后端无法区分不同表单字段的边界,直接解析失败
  • 传FormData时后端用[FromBody]:[FromBody]默认只会按照JSON/XML格式解析请求体,不会处理multipart表单结构,必然绑定为null
  • 用application/json/application/x-www-form-urlencoded头搭配FormData:请求头声明的格式和实际请求体格式不匹配,后端解析逻辑错位
  • 字段名大小写不匹配:你之前前端传的是全小写的username/password,后端实体类是首字母大写的Username/Password,如果接口配置了严格命名策略就会绑定失败,最稳妥的方式是前后端字段名完全一致

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.31 12:18:17