Python客户端上传文件至.NET6后端时IFormFile内容为空如何解决
.NET 6接收Python requests上传文件时IFormFile长度为0问题修复
问题现象
- Python客户端使用requests库向.NET 6后端接口上传文件,后端接收到的
IFormFile参数Length属性为0,无有效文件内容 - 使用Insomnia等接口调试工具上传同一个文件时,接口可正常接收文件,无异常
问题复现代码
Python客户端代码:
files = {'file': open(str(file_uuid), 'rb')} requests.post(' https://localhost:5001/Measurement', files=files, verify=False)
.NET 6后端接口代码:
[HttpPost("")] [AllowAnonymous] [Consumes("multipart/form-data")] [DisableRequestSizeLimit] public async Task<IActionResult> Post(IFormFile file) { await using var memoryStream = new MemoryStream(); await file.CopyToAsync(memoryStream); memoryStream.Position = 0; // 后续业务处理逻辑 }
根因分析
该问题的核心触发原因是 requests库直接传入裸文件对象时,生成的multipart/form-data报文分块缺失必填的filename字段,.NET 6的模型绑定逻辑会将未携带filename的multipart分块识别为普通表单字段,而非文件类型,最终绑定得到空的IFormFile对象。
另外两个可能的触发点:
- 请求URL前带有多余空格,导致请求路由匹配异常
- 文件对象在传入requests前已经被读取过,文件指针偏移到末尾,实际发送的内容为空
修复方案
- 调整Python端上传逻辑,显式指定文件上传的元信息,移除URL中多余的空格,修正后代码如下:
import os import requests file_path = str(file_uuid) file_name = os.path.basename(file_path) # 以三元组形式传入:(文件名, 文件流, MIME类型),with语句自动管理文件资源 with open(file_path, 'rb') as f: files = { 'file': (file_name, f, 'application/octet-stream') } # 移除URL开头的多余空格 resp = requests.post( 'https://localhost:5001/Measurement', files=files, verify=False )
- 如果文件对象在传入requests前执行过读取操作,需要先调用
seek(0)将文件指针重置到起始位置:
f = open(file_path, 'rb') f.read() # 前置读取操作 f.seek(0) # 指针重置到文件开头 # 再将f传入files参数发起请求
- (可选兼容配置)如果调整客户端后仍存在绑定异常,可在.NET 6项目的
Program.cs中添加表单配置,放宽绑定限制:
builder.Services.Configure<FormOptions>(options => { options.MultipartBodyLengthLimit = long.MaxValue; options.ValueLengthLimit = int.MaxValue; options.MemoryBufferThreshold = int.MaxValue; });
内容的提问来源于stack exchange,提问作者Sisky
相关产品推荐
相关产品推荐

