ASP.NET Core 2.2 Web API中int与decimal类型[Required]校验不生效
问题根因
int、decimal类型的[Required]校验不生效,本质是值类型的默认值逻辑和[Required]的判定规则不匹配:
- 当前定义的
mrNo是非空int值类型,当请求体完全没有传入mrNo字段时,JSON反序列化过程会直接给这个属性赋值为int的默认值0。 [Required]的核心判定逻辑是检查属性值是否为null,对非空值类型来说,它永远不会等于null,哪怕没传参数,校验器也会判定这个字段已经提供了值,自然不会触发必填校验错误。- 对比能正常生效的字符串
type字段:string是引用类型,没传值时属性为null,刚好命中[Required]的校验条件,所以仅传mrNo、缺失type的场景下,校验能正常触发返回400错误。
适配.NET Core 2.2的修复方案
方案1:将值类型改为可空类型,最通用的实现方式
直接把非空的int、decimal属性改成对应的可空类型,让未传值时属性为null,就能被[Required]正常捕获:
public class IcuTherapyO2Request { // 改为可空int,未传值时默认值为null [Required(ErrorMessage = "Mr Number is required")] public int? mrNo { get; set; } [Required(ErrorMessage = "Type is required")] public string type { get; set; } }
- 改完后,当请求体完全缺失
mrNo字段时,属性值为null,会立刻触发[Required]的校验逻辑,返回预期的400错误和对应提示。 - 注意:在后续业务逻辑中使用该属性时,需要对null值做兼容判断,避免触发空引用异常。
方案2:用范围校验兜底默认0值场景
如果业务上不希望把属性改成可空类型,可以补充[Range]校验特性,排除默认值0的合法资格:
public class IcuTherapyO2Request { // 假设mrNo的合法取值范围是1到int最大值 [Required(ErrorMessage = "Mr Number is required")] [Range(1, int.MaxValue, ErrorMessage = "Mr Number must be a valid positive number")] public int mrNo { get; set; } [Required(ErrorMessage = "Type is required")] public string type { get; set; } }
- 这个方案的逻辑是:未传
mrNo时属性值为0,刚好落在Range校验的范围外,触发校验错误。 - 局限:如果你的业务场景本身允许该数字参数取0值,这个方案就不适用。
补充说明:ASP.NET Core 2.2没有针对非空值类型缺失的自动校验配置,不存在改启动配置就能解决的捷径,必须通过上述模型定义的调整才能实现预期的必填校验效果。
内容的提问来源于stack exchange,提问作者Gvs Akhil
相关产品推荐
相关产品推荐

