手动添加multipart/form-data请求头致ASP.NET Core 7文件上传异常
手动设置Content-Type导致FormData上传无法命中ASP.NET Core端点的原因与解决方案
问题原因
当通过Fetch API发送FormData时,浏览器会自动生成完整的Content-Type请求头,格式为multipart/form-data; boundary=----WebKitFormBoundaryxxxxxx(不同浏览器前缀略有差异)。其中的boundary是分隔表单字段内容的核心标识,没有它,服务器无法正确解析表单数据结构。
如果手动添加headers.append('Content-Type', 'multipart/form-data');,会覆盖浏览器自动生成的完整头信息,导致请求头仅包含multipart/form-data,缺失关键的boundary参数。ASP.NET Core的请求解析器无法识别这种不完整的表单格式,因此无法匹配带有[FromForm]特性的v1/upload端点。
最佳解决方案
直接删除手动设置Content-Type的代码,让浏览器自动处理请求头即可:
修改后的JavaScript核心代码片段:
async function postFileAsync(file) { const formData = new FormData(); formData.append("file", file); const endpointUrl = "https://localhost:5001/v1/upload"; const result = await fetch(endpointUrl, { method: 'POST', cache: 'no-cache', // 完全省略headers字段,或保留空Headers对象,浏览器都会自动添加带boundary的正确Content-Type body: formData }); // 后续处理逻辑不变 }
特殊场景下的可选方案(不推荐)
如果因业务需求必须手动设置Content-Type,需要手动生成并绑定匹配的boundary,但此操作繁琐且易出错,仅建议极端场景使用:
async function postFileAsync(file) { const boundary = `----WebKitFormBoundary${Math.random().toString(16).slice(2)}`; const headers = new Headers(); headers.append('Content-Type', `multipart/form-data; boundary=${boundary}`); const formData = new FormData(); formData.append("file", file); // 注意:需手动按指定boundary序列化FormData,否则Fetch默认序列化会使用独立的boundary,导致格式不匹配 // ... 手动序列化FormData的复杂逻辑 }
验证说明
删除手动设置的Content-Type后,浏览器会自动生成包含boundary的标准请求头,ASP.NET Core即可正常解析FormData中的文件,成功命中v1/upload端点。
内容的提问来源于stack exchange,提问作者Wasyster
相关产品推荐
相关产品推荐

