.NET Core [FromBody]缺失必填值返回默认值而非400错误如何解决
解决方案
问题原因
该现象是C#值类型特性与ASP.NET Core默认模型校验逻辑共同导致的:
int/bool/DateTimeOffset都属于值类型,默认不允许为null,即使请求中未携带对应字段,反序列化时也会自动赋值为对应类型的默认值(如int默认0、bool默认false、DateTimeOffset默认0001-01-01)。默认[Required]特性仅校验属性是否为null,非null就判定校验通过,因此不会触发400错误。List<>属于引用类型,未传字段时反序列化结果为null,自然会触发[Required]校验规则返回400。
可用修复方案
方案1:将值类型声明为可空类型(最推荐)
直接修改DTO的属性为可空值类型,未传字段时属性值为null,即可触发[Required]校验:
namespace MyNamespace.DTO { public class MyDTO { [Required] public int? someNumber { get; set; } [Required] public bool? someBool { get; set; } [Required] public DateTimeOffset? someDate { get; set; } } }
该方案无需修改全局配置,兼容所有校验逻辑,适用绝大多数场景。
方案2:修改全局校验配置(适合不想改动DTO的场景)
如果不需要修改DTO定义,可在.NET 6+的Program.cs中配置Mvc选项,要求非可空值类型必须显式在请求中提供:
var builder = WebApplication.CreateBuilder(args); builder.Services.AddControllers() .AddMvcOptions(options => { // 开启非可空值类型的隐式必填校验 options.SuppressImplicitRequiredAttributeForNonNullableValueTypes = false; });
如果你项目用的是Newtonsoft.Json而非默认的System.Text.Json,还需补充反序列化配置:
builder.Services.AddControllers() .AddNewtonsoftJson(options => { options.SerializerSettings.DefaultValueHandling = Newtonsoft.Json.DefaultValueHandling.IgnoreAndPopulate; });
方案3:使用[BindRequired]特性替代[Required]
[BindRequired]会强制要求属性必须出现在请求绑定数据中,即使值类型默认值合法,只要字段缺失就会触发校验失败:
namespace MyNamespace.DTO { public class MyDTO { [BindRequired] public int someNumber { get; set; } [BindRequired] public bool someBool { get; set; } [BindRequired] public DateTimeOffset someDate { get; set; } } }
提示:该方案仅校验字段是否缺失,如果客户端显式传入了对应类型的默认值(如
someNumber:0),仍会判定校验通过。
额外注意:如果你的项目手动关闭了自动模型校验过滤器,需要自行在控制器中判断
ModelState.IsValid,为false时返回BadRequest(ModelState)即可。
内容的提问来源于stack exchange,提问作者Asghwor
相关产品推荐
相关产品推荐

