如何从React向ASP.NET Core API发送带文件的表单数据
问题根因
你试遍所有组合都拿不到值,核心是踩了三个高频错误:
- 手动给FormData请求设置
Content-Type头,导致浏览器丢失自动生成的boundary分隔符,后端无法解析表单边界 - 后端绑定特性和请求格式不匹配:用
[FromBody]接收FormData数据,而[FromBody]仅负责反序列化JSON/XML格式的请求体 - 前后端字段命名不匹配、请求头和请求体格式错配
正确实现步骤
先调通普通表单字段传输,再追加文件字段即可,不需要用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
相关产品推荐
相关产品推荐

