FluentValidation如何配置多层深度嵌套集合自定义验证器
结论
你预期的连续链式写法不可行,无法直接编译通过。
原因
FluentValidation的规则构建上下文是绑定当前规则的操作类型的:当你写RuleFor(x=>x.Modules)时,返回的规则构建器是针对Training类型下的Modules集合(即ICollection<Module>类型)做配置,后续直接跟.RuleFor()要求传入的表达式必须访问根类型Training的直属属性,无法直接访问集合元素Module下的Phases属性,自然没法顺着层级往下连写。
正确配置方式
根据你当前不需要校验中间层Module、Phase字段的需求,直接在TrainingValidator里用嵌套RuleForEach+ChildRules的写法就能实现全层级Question的校验,不需要为中间层额外写验证器:
public class TrainingValidator : AbstractValidator<Training> { public TrainingValidator() { // 此处编写Training自身字段的校验规则即可 // 例:RuleFor(t => t.TrainingTitle).NotEmpty().MaximumLength(100); // 多层级集合校验配置 RuleForEach(t => t.Modules) .ChildRules(moduleRule => { moduleRule.RuleForEach(m => m.Phases) .ChildRules(phaseRule => { phaseRule.RuleForEach(p => p.Questions) .SetValidator(new QuestionValidator()); }); }); } }
如果后续你需要给Module、Phase也加校验规则,可以为中间层补充对应验证器,写法会更简洁,也方便后续维护:
// Module验证器,后续新增Module字段校验直接在构造函数中编写即可 public class ModuleValidator : AbstractValidator<Module> { public ModuleValidator() { RuleForEach(m => m.Phases).SetValidator(new PhaseValidator()); } } // Phase验证器,后续新增Phase字段校验直接在构造函数中编写即可 public class PhaseValidator : AbstractValidator<Phase> { public PhaseValidator() { RuleForEach(p => p.Questions).SetValidator(new QuestionValidator()); } } // Training验证器最终可简化为 public class TrainingValidator : AbstractValidator<Training> { public TrainingValidator() { // Training自身字段校验规则 RuleForEach(t => t.Modules).SetValidator(new ModuleValidator()); } }
两种写法效果完全一致:所有嵌套层级下的Question都会自动调用你已经写好的QuestionValidator完成校验,校验返回的错误路径会自动带上层级索引,能直接定位到具体是哪个Module、哪个Phase下的Question字段不合法。
内容的提问来源于stack exchange,提问作者americanslon
相关产品推荐
相关产品推荐

