Fluent Validation:如何复用属性的验证规则?
复用FluentValidation中Group属性验证规则的方案
针对你在.NET 7项目中结合MediatR CQRS架构使用FluentValidation 11.8.1时遇到的重复验证规则问题,以下两种方案可以高效实现Group属性验证逻辑的复用:
方案一:封装验证扩展方法
通过扩展IRuleBuilder,将Group属性的通用验证规则封装成可复用的扩展方法,无需修改请求类结构,直接在各验证器中调用即可。
步骤1:创建验证扩展类
using FluentValidation; public static class GroupValidationExtensions { /// <summary> /// 复用Group属性的通用验证规则 /// </summary> public static IRuleBuilder<T, string> ApplyGroupValidationRules<T>(this IRuleBuilder<T, string> ruleBuilder) { return ruleBuilder .NotEmpty().WithMessage("Group不能为空") .MaximumLength(50).WithMessage("Group长度不能超过50个字符") .Matches(@"^[A-Za-z0-9_-]+$").WithMessage("Group仅允许包含字母、数字、下划线和短横线"); } }
步骤2:在验证器中调用扩展方法
public class CreateGroupValidator : AbstractValidator<CreateGroupRequest> { public CreateGroupValidator() { ClassLevelCascadeMode = CascadeMode.Stop; // 复用Group验证规则 RuleFor(x => x.Group).ApplyGroupValidationRules(); // 添加Create请求专属验证规则 RuleFor(x => x.Description).NotEmpty().MaximumLength(200); } } public class UpdateGroupValidator : AbstractValidator<UpdateGroupRequest> { public UpdateGroupValidator() { ClassLevelCascadeMode = CascadeMode.Stop; // 复用Group验证规则 RuleFor(x => x.Group).ApplyGroupValidationRules(); // 添加Update请求专属验证规则 RuleFor(x => x.Id).NotEmpty(); } }
方案二:使用抽象基类验证器
如果后续有更多包含Group属性的请求类,可以定义一个带通用验证逻辑的抽象基类,让所有相关验证器继承该基类,同时统一设置ClassLevelCascadeMode。
步骤1:定义共享接口(可选但推荐)
为所有包含Group属性的请求类定义统一接口,增强类型约束:
public interface IGroupRequest { string Group { get; set; } }
让请求类实现该接口:
public class CreateGroupRequest : IRequest<Unit>, IGroupRequest { public string Group { get; set; } public string Description { get; set; } } public class UpdateGroupRequest : IRequest<Unit>, IGroupRequest { public Guid Id { get; set; } public string Group { get; set; } }
步骤2:创建抽象基类验证器
using FluentValidation; public abstract class BaseGroupRequestValidator<T> : AbstractValidator<T> where T : IGroupRequest { protected BaseGroupRequestValidator() { // 统一设置级联模式,无需在子类重复定义 ClassLevelCascadeMode = CascadeMode.Stop; // 定义Group属性的通用验证规则 RuleFor(x => x.Group) .NotEmpty().WithMessage("Group不能为空") .MaximumLength(50).WithMessage("Group长度不能超过50个字符") .Matches(@"^[A-Za-z0-9_-]+$").WithMessage("Group仅允许包含字母、数字、下划线和短横线"); } }
步骤3:子类验证器继承基类
public class CreateGroupValidator : BaseGroupRequestValidator<CreateGroupRequest> { public CreateGroupValidator() { // 仅需添加Create请求专属规则 RuleFor(x => x.Description).NotEmpty().MaximumLength(200); } } public class UpdateGroupValidator : BaseGroupRequestValidator<UpdateGroupRequest> { public UpdateGroupValidator() { // 仅需添加Update请求专属规则 RuleFor(x => x.Id).NotEmpty(); } }
方案对比
- 扩展方法:更灵活,无需修改请求类结构,适合零散的属性规则复用场景。
- 抽象基类:更规整,能统一设置级联模式等全局验证配置,适合有大量共享验证逻辑的场景。
内容的提问来源于stack exchange,提问作者Bhanu
相关产品推荐
相关产品推荐

