如何忽略类自定义验证Attribute在指定对象/属性上的验证
解决方案
方案1:新增忽略特性(你提出的思路完全可行)
步骤1:定义忽略标记特性
[AttributeUsage(AttributeTargets.Property, AllowMultiple = false)] public class IgnoreTranslationValidationAttribute : Attribute { }
步骤2:修改原有验证特性的逻辑
在ValidateTranslationDictionaryAttribute的验证入口处增加忽略检查:
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property, Inherited = true, AllowMultiple = false)] public class ValidateTranslationDictionaryAttribute : ValidationAttribute { public ValidateTranslationDictionaryAttribute() : base() { } protected override ValidationResult IsValid(object value, ValidationContext validationContext) { // 检查当前验证的属性是否标记了忽略验证 if (validationContext.MemberName != null) { var property = validationContext.ObjectType.GetProperty(validationContext.MemberName); if (property != null && property.IsDefined(typeof(IgnoreTranslationValidationAttribute), inherit: true)) { return ValidationResult.Success; } } // 保留原有验证逻辑 DoSomeValidationHere(); return ValidationResult.Success; } }
步骤3:在需要跳过验证的属性上标记即可
public class Test{ public Translations WithValidation{ get; set; } [IgnoreTranslationValidation] public Translations WithoutValidation{ get; set; } }
该方案侵入性极低,不需要修改原有已上线的特性声明,也不会出现验证重复执行的问题。
方案2:优化原有特性的开关逻辑,解决重复执行问题
你之前加开关但验证执行两次的原因是类、属性上的特性实例都被触发了,只需在逻辑里增加优先级判断:属性级的特性配置优先级高于类级,即可避免重复执行。
步骤1:给原有特性增加开关和优先级判断
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property, Inherited = true, AllowMultiple = false)] public class ValidateTranslationDictionaryAttribute : ValidationAttribute { // 验证开关,默认开启 public bool EnableValidation { get; set; } = true; public ValidateTranslationDictionaryAttribute() : base() { } protected override ValidationResult IsValid(object value, ValidationContext validationContext) { if (validationContext.MemberName != null) { var property = validationContext.ObjectType.GetProperty(validationContext.MemberName); if (property != null) { var propertyAttr = property.GetCustomAttribute<ValidateTranslationDictionaryAttribute>(inherit: true); // 如果属性上已声明该特性,直接跳过类级的特性实例执行 if (propertyAttr != null && !Equals(propertyAttr, this)) { return ValidationResult.Success; } // 按当前特性的开关判断是否执行验证 if (!EnableValidation) { return ValidationResult.Success; } } } // 保留原有验证逻辑 DoSomeValidationHere(); return ValidationResult.Success; } }
步骤2:在需要跳过验证的属性上配置开关即可
public class Test{ public Translations WithValidation{ get; set; } [ValidateTranslationDictionary(EnableValidation = false)] public Translations WithoutValidation{ get; set; } }
该方案不需要新增额外的特性类,也彻底解决了验证重复执行的问题。
内容的提问来源于stack exchange,提问作者khaled saleh
相关产品推荐
相关产品推荐

