asp.net core 中通过 requestsizelimit 特性可限制整个请求体大小(如[requestsizelimit(20_000_000)]),但需同步配置 iis、kestrel 或 nginx 等宿主限制,并手动校验单文件大小及流式处理大文件以避免内存溢出。

ASP.NET Core 中通过 RequestSizeLimit 控制上传大小
在 ASP.NET Core 服务端限制上传文件大小,最直接的方式是使用 RequestSizeLimit 特性。它作用于整个请求体(包括表单字段和文件),单位是字节。
常见错误是只改了前端或中间件配置,却漏掉这个全局限制,导致大文件上传直接返回 413 Payload Too Large 错误,且不进控制器逻辑。
- 在控制器方法上加:
[RequestSizeLimit(20_000_000)](限制 20MB) - 若需全局生效,在
Program.cs中配置:app.Use((context, next) => { context.Features.Get<IHttpMaxRequestBodySizeFeature>().MaxRequestBodySize = 20_000_000; return next(); }); - 注意:该设置必须在
UseRouting之后、UseEndpoints之前注册,否则无效
IIS 或 Kestrel 部署时的额外限制
即使代码里设了 RequestSizeLimit,实际部署后仍可能被宿主服务器拦截——这是最容易被忽略的一环。
IIS 默认限制为 30MB(28.6MiB),Kestrel 默认仅 30MB(31,457,280 字节)。超出会直接断连,连 413 都不返回。
- IIS:修改
web.config的<requestlimits maxallowedcontentlength="20971520"></requestlimits>(单位字节) - Kestrel:在
Program.cs中配置options.Limits.MaxRequestBodySize = 20_000_000; - Linux + Nginx:还需检查
client_max_body_size指令是否同步调整
区分单文件 vs 总请求体大小的判断逻辑
RequestSizeLimit 限制的是整个 HTTP 请求体,不是单个文件。如果表单含多个文件+文本字段,总大小超限就会失败,但你无法从框架层直接知道是哪个文件导致的。
真正需要“单文件大小校验”的场景,得手动解析 IFormFile:
- 在 Action 中遍历
Request.Form.Files - 对每个
IFormFile检查file.Length,再抛出明确提示(如BadRequest("文件 xxx 超过 10MB")) - 注意:必须先调用
file.OpenReadStream()或访问Length才能触发底层读取,否则某些情况下长度可能为 0
大文件上传时的内存与流处理风险
用 IFormFile.CopyToAsync 直接保存,小文件没问题;但上传 100MB 文件时,若未指定缓冲区或未用流式处理,容易触发 OutOfMemoryException 或阻塞线程。
- 避免
file.CopyTo(同步阻塞);优先用CopyToAsync并传入new FileStream(...) - 不要把整个
IFormFile读进MemoryStream,尤其在高并发下 - 考虑搭配
DisableRequestSizeLimit+ 手动流校验,适用于需支持超大文件但又要求精准控制的场景
真正麻烦的从来不是设个数字,而是所有环节——代码限制、宿主配置、反向代理、客户端行为、流处理方式——必须全部对齐,缺一不可。










