ASP.NET Core 上传文件主要通过
IFormFile接口实现,它封装了 HTTP 表单中上传的单个文件数据。核心思路是:前端用
<input type="file">提交,后端在控制器方法中接收
IFormFile或
IFormFileCollection参数,再读取、验证、保存。
基础单文件上传(IFormFile)
这是最常用的方式,适用于上传一个文件(如头像、单个文档)。
确保 HTML 表单使用enctype="multipart/form-data",否则文件不会被发送 控制器方法参数直接声明为
IFormFile,框架会自动绑定 检查
file != null && file.Length > 0避免空上传 推荐用
Path.GetRandomFileName()生成安全文件名,避免路径遍历或重名
示例代码:
后端 Action:
[HttpPost]public async Task
{
if (file == null || file.Length == 0)
return BadRequest("请选择文件");
var uploadsRoot = Path.Combine(Directory.GetCurrentDirectory(), "wwwroot", "uploads");
Directory.CreateDirectory(uploadsRoot);
var fileName = Path.GetRandomFileName() + Path.GetExtension(file.FileName);
var filePath = Path.Combine(uploadsRoot, fileName);
using var stream = new FileStream(filePath, FileMode.Create);
await file.CopyToAsync(stream);
return Ok(new { FileName = fileName });
}
多文件上传(IFormFileCollection)
当需要一次上传多个文件(如批量图片),前端 input 的
name属性要一致,并加
multiple属性。 后端接收类型改为
IFormFileCollection逐个遍历处理,注意总大小限制(比如所有文件加起来不超过 100MB) 可结合
ModelState.IsValid或手动校验扩展名、MIME 类型
对应 Action:
public async Task{
if (!files.Any()) return BadRequest();
long totalSize = files.Sum(f => f.Length);
if (totalSize > 100 * 1024 * 1024) // 100MB
return BadRequest("总文件大小不能超过 100MB");
// 逐个保存...
}
大文件上传与流式处理
上传超大文件(如视频、备份包)时,避免一次性加载进内存,应使用流式读取。
不要调用file.CopyToAsync()到内存流,而是直接写入目标文件流 启用请求体大小限制调整(默认 128MB),需在
Program.cs中配置 建议配合进度条,前端可用
XMLHttpRequest.upload.onprogress或
fetch+
ReadableStream
配置示例(Program.cs):
builder.Services.Configure{
options.Limits.MaxRequestBodySize = 500 * 1024 * 1024; // 500MB
});
// 或用 [RequestSizeLimit(500_000_000)] 特性标记 Action
安全与验证要点
仅靠前端限制不可靠,后端必须做关键校验。
文件扩展名白名单:如只允许.jpg, .png, .pdf,用
Path.GetExtension(file.FileName).ToLowerInvariant()判断 MIME 类型检查:读取文件前几个字节(magic number),比
file.ContentType更可靠(该字段由浏览器提供,可伪造) 防止路径遍历:永远不要直接拼接
file.FileName到路径中;用
Path.GetFileName()或更稳妥的随机名 防恶意文件:对上传后的文件,必要时用杀毒引擎扫描(生产环境建议)
基本上就这些。IFormFile 是 ASP.NET Core 文件上传的基石,用法直接但细节不少——重点是安全校验和流式处理意识,别让大文件拖垮服务器,也别让恶意文件钻了空子。
