ASP.NET Core 6最小API POST绑定自定义类型提示无请求体错误怎么办
问题根源
这个问题是.NET 6 RC版本最小API的已知绑定逻辑缺陷,同时最小API和控制器的默认参数绑定规则存在差异:
- 控制器对于POST请求的复杂类型参数,默认会自动从请求体绑定,不需要加
[FromBody]特性,且对分块传输(Transfer-Encoding: chunked)的请求判断逻辑正常 - .NET 6 RC版本的最小API隐式推断请求体绑定时,错误将
Content-Length请求头的存在性作为判断是否有请求体的依据,当你用Postman发送分块传输的POST请求时(比如请求体较大时Postman会自动用分块传输),没有Content-Length头,框架就会误判为没有请求体,抛出你遇到的错误。而你直接读取HttpRequest.BodyReader时不受这个逻辑限制,所以可以正常拿到请求体内容。
解决方案
- 优先显式指定[FromBody]特性
直接在参数前加上[FromBody],跳过框架的隐式推断逻辑,即可解决大部分场景的问题:
endpoints.MapPost("/api/user/test", ([FromBody] NewUserRequest request) => { /* 原有业务逻辑 */ });
升级到.NET 6正式版
这个绑定bug在.NET 6正式发布版本中已经被修复,升级后即使不加[FromBody]也可以正常绑定分块传输的POST请求体。临时兼容方案(未升级正式版时使用)
如果暂时不能升级正式版本,可以在中间件管道的最开头开启请求体缓冲,避免绑定逻辑读不到请求体:
var builder = WebApplication.CreateBuilder(args); // ... 其他服务注册逻辑 var app = builder.Build(); // 放在所有中间件的最前面 app.Use((context, next) => { context.Request.EnableBuffering(); return next(context); }); // ... 其他中间件、终结点配置 app.Run();
补充排查点
如果上面的方案都无效,可以检查以下配置:
- 确认
NewUserRequest类没有自定义TryParse或者BindAsync静态方法,否则框架会优先使用这些方法走非请求体的绑定逻辑 - 确认没有其他自定义中间件在终结点执行前读取了请求体,且没有将请求体的
Position重置为0
内容的提问来源于stack exchange,提问作者moswald
相关产品推荐
相关产品推荐

