C#限制上传文件大小 C#如何在服务端控制上传文件的大小

6次阅读

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

C#限制上传文件大小 C#如何在服务端控制上传文件的大小

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 + 手动流校验,适用于需支持超大文件但又要求精准控制的场景

真正麻烦的从来不是设个数字,而是所有环节——代码限制、宿主配置、反向代理、客户端行为、流处理方式——必须全部对齐,缺一不可。

text=ZqhQzanResources