MaxRequestBodySize 设置无效是因为 ASP.NET Core 存在 Kestrel 和 MVC 两层请求体大小限制,必须同时配置二者才生效。

为什么 MaxRequestBodySize 设置无效?
常见现象是设置了 Kestrel 的 MaxRequestBodySize,但上传超过 30MB 的文件仍报 413 错误。根本原因在于 ASP.NET Core 中有两层限制:Kestrel 自身的请求体大小限制,以及 MVC 层的 RequestSizeLimit 或 DisableRequestSizeLimit 特性。两者必须同时调整才生效。
实操建议:
- 若用
WebHostBuilder(.NET Core 2.x),在ConfigureKestrel中设MaxRequestBodySize,单位是字节;设为null表示不限制(不推荐生产环境) - 若用
HostBuilder(.NET Core 3.0+),改用ConfigureWebHostDefaults+ConfigureKestrel - 控制器方法上必须显式加
[RequestSizeLimit(100_000_000)],或用[DisableRequestSizeLimit](绕过 MVC 层限制) - 若用
IFormFile接收文件,还要注意FormOptions.MultipartBodyLengthLimit(已弃用于 .NET 6+,由 Kestrel 统一接管)
.NET 6+ 中推荐的 Kestrel 全局配置方式
.NET 6 起,MaxRequestBodySize 默认为 30MB(31457280 字节),且不能设为 null —— 必须设具体值或使用 long.MaxValue 模拟“不限制”。配置需在 Program.cs 的 builder.WebHost.ConfigureKestrel 中完成。
示例代码:
builder.WebHost.ConfigureKestrel(serverOptions =>
{
serverOptions.Limits.MaxRequestBodySize = 100_000_000; // 100MB
});
注意:
- 该设置影响所有端点,包括非上传接口,可能带来 DoS 风险
- 若只对某几个路由放宽限制,应配合控制器级
[RequestSizeLimit]使用,而非全局调大 - 反向代理(如 Nginx、IIS)也有自己的请求体限制,必须同步检查并调整(例如 Nginx 的
client_max_body_size)
上传大文件时为何仍卡在 120 秒超时?
MaxRequestBodySize 只控制体积,不控制时间。Kestrel 默认 KeepAliveTimeout 和 RequestHeadersTimeout 不影响上传耗时,但 IdleTimeout 会 —— 它定义了连接空闲多久后断开。大文件上传过程中若传输速率低、出现暂停,可能触发该超时。
解决办法:
- 延长
IdleTimeout,例如设为TimeSpan.FromMinutes(10) - 仅对上传专用端点调整,避免全局降低安全性
- 前端应实现分片上传 + 断点续传,比单纯调大超时更可靠
ASP.NET Core 8 中的变更与兼容提醒
.NET 8 默认启用 RequestDelegateFactory,但 [RequestSizeLimit] 仍有效;不过若用了 Minimal Hosting 模式(无控制器类),就得改用 MapPost 的 DisableRequestSizeLimit() 扩展方法:
app.MapPost("/upload", async (HttpContext ctx) =>
{
// ...
}).DisableRequestSizeLimit();
容易被忽略的点:
-
DisableRequestSizeLimit()是终结点级 API,不是中间件,不能链在UseRouting后面随便加 - 若同时用了
MapControllers()和MapMinimalActions(),两套限制机制要分别处理 - Health Check、Swagger 等内置端点默认继承全局限制,上传接口若复用相同路径前缀,可能意外受限










