如何为FluentValidation创建ValidateWhenNotEmpty扩展方法
封装FluentValidation的
ValidateWhenNotEmpty扩展方法 需求背景
在使用FluentValidation时,需要为属性添加仅当非空/非null时才执行的验证规则,现有写法.When(x => !string.IsNullOrWhiteSpace(x.Property))重复冗长,希望封装为通用扩展方法ValidateWhenNotEmpty(),满足:
- 跳过null/空字符串的验证
- 兼容任意验证链(如
EmailAddress()、Matches()) - 不为空字段触发“必填”错误
- 支持所有数据类型的泛型版本
解决方案
将以下扩展方法添加到现有CommonValidators静态类中:
1. 字符串专属版本(精准处理字符串空值)
// 针对字符串类型:仅当非空/非null时执行后续验证 public static IRuleBuilderOptions<T, string> ValidateWhenNotEmpty<T>(this IRuleBuilderOptions<T, string> rule) { return rule.When(x => !string.IsNullOrWhiteSpace(x)); }
2. 泛型版本(适配所有数据类型)
// 泛型版本:支持所有数据类型,仅当属性非null/非默认值时执行后续验证 public static IRuleBuilderOptions<T, TProperty> ValidateWhenNotEmpty<T, TProperty>(this IRuleBuilderOptions<T, TProperty> rule) { return rule.When(x => { // 引用类型:判断是否为null if (typeof(TProperty).IsClass && x == null) return false; // 值类型:判断是否不等于默认值 if (typeof(TProperty).IsValueType) return !EqualityComparer<TProperty>.Default.Equals(x, default); return true; }); }
使用示例
字符串属性场景
替代原有冗长的When语句:
RuleFor(x => x.WebsiteURL) .ValidateAgentWebsiteUrl() .ValidateWhenNotEmpty();
泛型数据类型场景(如int)
针对值类型,仅当属性不为默认值时执行验证:
// 仅当Age提供了非默认值时,验证是否大于18 RuleFor(x => x.Age) .GreaterThan(18).WithMessage("Age must be over 18 if provided") .ValidateWhenNotEmpty();
说明
- 字符串版本专门处理
string类型,使用string.IsNullOrWhiteSpace确保精准判断空/空白字符串 - 泛型版本自动区分引用类型(判断null)和值类型(判断是否为默认值),适配所有数据类型
- 该方法仅跳过空值验证,不会添加
NotEmpty()规则,因此不会触发“必填”错误
内容的提问来源于stack exchange,提问作者Jayachandran
相关产品推荐
相关产品推荐

