Fluent Validation如何实现CreditCard()校验规则取反
Fluent Validation 禁止字段包含信用卡号的实现方案
你不需要编写晦涩的反向正则,有两种可读性、可维护性都更好的实现方式:
方式1:高版本直接用官方内置取反修饰符
如果你使用的是 Fluent Validation 11.0及以上版本,官方已经原生支持规则取反逻辑,你之前找的.Not().CreditCard()写法是直接可用的:
RuleFor(x => x.TargetField) .Not().CreditCard() .WithMessage("禁止提交信用卡号等敏感数据");
低版本不存在这个API,所以检索旧文档或使用低版本类库时找不到相关实现。
方式2:低版本用Must规则复用内置校验逻辑
如果你的项目用的是11.0以下的版本,不需要自己写正则匹配,直接通过Must()规则复用官方内置的信用卡校验器即可,逻辑和官方判定标准完全一致,不会出现误判漏判:
RuleFor(x => x.TargetField) .Must(fieldValue => { // 空值走独立的非空校验逻辑,当前规则直接放行 if (string.IsNullOrWhiteSpace(fieldValue)) return true; var creditCardChecker = new CreditCardValidator(); var checkResult = creditCardChecker.Validate(new ValidationContext<string>(fieldValue)); // 若内置校验判定为合法信用卡号,返回false触发校验失败 return !checkResult.IsValid; }) .WithMessage("字段内容包含禁止提交的信用卡敏感信息");
可复用封装方案
如果这个规则在项目里要多次使用,可以封装成和原生API风格一致的扩展方法,避免重复写逻辑:
public static class CustomValidationExtensions { public static IRuleBuilderOptions<T, string> NotContainCreditCard<T>( this IRuleBuilder<T, string> ruleBuilder) { return ruleBuilder.Must(value => { if (string.IsNullOrWhiteSpace(value)) return true; var validator = new CreditCardValidator(); var result = validator.Validate(new ValidationContext<string>(value)); return !result.IsValid; }) .WithMessage("禁止提交信用卡号等敏感数据"); } }
封装后调用方式和内置方法完全一致:
RuleFor(x => x.Content).NotContainCreditCard();
不推荐使用反向正则方案:一方面不同卡组织的卡号规则会动态更新,自行维护正则的成本高、容易出现判定偏差;另一方面反向匹配的正则逻辑晦涩,代码可读性差,后续迭代很容易出问题。直接复用官方内置的信用卡校验逻辑,能始终和官方判定标准保持对齐。
内容的提问来源于stack exchange,提问作者Valeriu Seremet
相关产品推荐
相关产品推荐

