IgnoreNulls验证特性对其他特性的影响及DataAnnotations迁移实现
从EnterpriseLibrary Validation迁移到DataAnnotations实现[IgnoreNulls]功能的方案
原生StringLengthAttribute的默认行为
System.ComponentModel.DataAnnotations.StringLengthAttribute 默认就支持忽略null值的逻辑:当目标属性为null时,它的验证逻辑不会触发,直接返回验证通过,和你原代码中[IgnoreNulls]+StringLengthValidator的组合效果完全一致。
示例代码:
public class Product { // Description为null时,StringLength不会触发验证 [StringLength(100)] public string Description { get; set; } }
自定义IgnoreNulls特性实现验证链短路
如果你的场景需要给多个验证器统一添加“null时跳过验证”的规则,或者要实现整条验证链的短路,可以自定义IgnoreNullsAttribute,并利用DataAnnotations的验证顺序特性实现短路:
- 自定义IgnoreNullsAttribute:
public class IgnoreNullsAttribute : ValidationAttribute { protected override ValidationResult IsValid(object value, ValidationContext validationContext) { // 值为null时直接返回验证通过,后续验证器不会执行 return value == null ? ValidationResult.Success : ValidationResult.Success; } }
- 使用时将其放在所有需要短路的验证特性之前:
public class Product { // Description为null时,IgnoreNulls返回成功,后续StringLength、RegularExpression都不会触发 [IgnoreNulls] [StringLength(100)] [RegularExpression(@"^[a-zA-Z0-9]+$")] public string Description { get; set; } }
注意:DataAnnotations的验证器是按照特性声明顺序执行的,因此[IgnoreNulls]必须放在最前面才能实现短路效果。
自定义支持IgnoreNulls开关的StringLength验证器
如果需要让StringLength验证器可以通过特性参数控制是否忽略null,可以自定义一个扩展的StringLengthAttribute:
public class StringLengthWithIgnoreNullsAttribute : StringLengthAttribute { public bool IgnoreNulls { get; set; } = true; public StringLengthWithIgnoreNullsAttribute(int maximumLength) : base(maximumLength) { } public override bool IsValid(object value) { // 开启IgnoreNulls且值为null时,直接返回验证通过 if (IgnoreNulls && value == null) { return true; } return base.IsValid(value); } }
使用时可以灵活配置:
public class Product { // 默认忽略null,null时不触发验证 [StringLengthWithIgnoreNulls(100)] public string Description { get; set; } // 关闭IgnoreNulls,null时会触发StringLength验证报错 [StringLengthWithIgnoreNulls(50, IgnoreNulls = false)] public string Name { get; set; } }
内容的提问来源于stack exchange,提问作者Shane
相关产品推荐
相关产品推荐

