ASP.NET Core 中 IFormFile 默认限100文件且易内存溢出,需配置 ValueCountLimit 和 MultipartBodyLengthLimit,并用 OpenReadStream 流式处理。

ASP.NET Core 中的 IFormFile 天然支持多文件上传,但直接用 Request.Form.Files 拿到的集合默认上限是 100 个文件,超出会静默截断——这不是 bug,是默认配置限制。
如何正确接收前端传来的多个文件
前端必须用 <input type="file" multiple>,且表单 enctype 必须为 "multipart/form-data"。后端不能依赖模型绑定自动映射到 IFormFile[] 数组(某些版本有绑定失败风险),推荐显式从 Request.Form.Files 取值:
var files = Request.Form.Files;
foreach (var file in files)
{
if (file.Length > 0)
{
// 处理单个文件
using var stream = file.OpenReadStream();
// ……
}
}- 不要写
public IActionResult Upload(IFormFile[] files)并期望框架自动填充——在 .NET 6+ 的 Minimal API 或部分 MVC 配置下可能为空 - 每个
file.FileName是原始客户端文件名,file.Name才是表单字段名(如"files") - 若前端用 JS 动态追加
FormData.append("files", blob)多次,后端仍能通过同名字段聚合到一个IFormFile集合中
为什么上传大文件或大量文件时请求直接 400 或 500
根本原因不是代码逻辑,而是 ASP.NET Core 默认对整个 multipart 请求体做了大小和数量限制:
-
MaxRequestBodySize默认 30MB(影响总上传体积) -
MultipartBodyLengthLimit在KestrelServerOptions中控制,但实际生效的是FormOptions.MultipartBodyLengthLimit(.NET 5+ 推荐设在ConfigureServices) - 更关键的是
FormOptions.ValueCountLimit和ValueLengthLimit,它们限制表单字段总数和单字段长度——上传 200 个文件时,即使每个都小,也可能因字段数超默认 1024 而被拒
需在 Program.cs 中调整:
builder.Services.Configure<FormOptions>(options =>
{
options.ValueCountLimit = 2000; // 允许最多 2000 个表单字段(含文件 + 普通 input)
options.MultipartBodyLengthLimit = 512 * 1024 * 1024; // 512MB
});如何避免内存爆满或上传中途失败
所有 IFormFile 默认加载进内存,批量上传几十个百兆文件极易触发 OutOfMemoryException。必须流式处理:
- 别调
file.CopyToAsync()到内存流;改用file.OpenReadStream()获取只读流,再分块拷贝到磁盘或云存储 - 上传过程中不 await 所有文件——用
Task.WhenAll()并发写入时,注意磁盘 I/O 或云 SDK 的并发连接数限制(如 Azure Blob 默认每客户端 100 连接) - 临时文件路径别硬编码
"./uploads",用Path.GetTempFileName()或注入IWebHostEnvironment.WebRootPath - 务必检查
file.Length == 0,空文件会被当成合法项传进来
真正难的不是“怎么传”,而是“怎么扛住 500 个用户同时上传 300 个文件”——限流、分片、断点续传、前端校验、服务端防重放,这些都不在 IFormFile 范围内。先确保单机单请求稳住,再谈分布式上传网关。


















