如何使用Or组合FluentValidation的多个验证条件?
用FluentValidation实现“空值或符合格式”的可读验证
你想要的这种可读性更强的写法确实可以实现,FluentValidation本身没有原生的Or()链式方法,但可以通过两种常用方式达成需求:
方法一:使用Unless简化逻辑
这是最简单的方案,无需额外扩展,直接利用FluentValidation自带的条件方法:
RuleFor(x => x.Property) // 验证属性是否符合数字格式 .Matches(@"^[0-9]+$") // 当属性为空时,跳过这个验证规则 .Unless(x => string.IsNullOrEmpty(x.Property));
这段代码的逻辑是:如果属性不为空,就必须符合指定的数字格式;如果为空,则自动通过验证,完全等价于你想要的“要么为空,要么符合格式”的需求。
方法二:自定义Or()扩展方法
如果你更倾向于Empty().Or().Matches(...)这种链式写法,可以通过扩展FluentValidation的规则构建器来实现:
第一步:创建扩展类
using FluentValidation; using FluentValidation.Validators; public static class FluentValidationOrExtensions { public static IRuleBuilderOptions<T, TProperty> Or<T, TProperty>( this IRuleBuilderOptions<T, TProperty> currentRule, Func<IRuleBuilder<T, TProperty>, IRuleBuilderOptions<T, TProperty>> nextRuleConfig) { var ruleBuilder = currentRule as RuleBuilder<T, TProperty>; if (ruleBuilder == null) return currentRule; // 创建新的规则并获取其验证器 var nextRule = nextRuleConfig(RuleBuilder<T, TProperty>.Create(ruleBuilder.Rule)); var nextValidator = nextRule.Rule.Validator; // 替换原规则的验证器为组合逻辑或验证器 ruleBuilder.Rule.Validator = new OrCompositeValidator { Validators = new List<IPropertyValidator> { ruleBuilder.Rule.Validator, nextValidator } }; return ruleBuilder; } // 自定义组合验证器,实现逻辑或 private class OrCompositeValidator : PropertyValidator { public List<IPropertyValidator> Validators { get; set; } = new(); public override bool IsValid(ValidationContext context, object value) { // 只要有一个验证器通过,就返回true return Validators.Any(v => v.IsValid(context, value)); } public override string Name => "OrCompositeValidator"; } }
第二步:使用扩展方法
引入扩展类的命名空间后,就可以像你期望的那样写验证规则了:
RuleFor(x => x.Property) .Empty() .Or(r => r.Matches(@"^[0-9]+$"));
这个扩展方法会把Empty()和Matches(...)两个验证规则组合成逻辑或的关系,只要满足其中一个条件就通过验证。
内容的提问来源于stack exchange,提问作者me.at.coding
相关产品推荐
相关产品推荐

