我正在尝试创建验证,它可以有两个组并在第一次失败时阻止第二次验证(它包含许多规则).
现在我确实在内部和’main validator’中创建了一个私有的’BasicValidation’类,如下所示:
RuleFor(m => m).SetValidator(new BasicValidation()).DependentRules(() => { //Complex validation RuleFor(m => m.IdOfSthInDb) .MustAsync(ItemMustExists) .WithMessage("Item does not exist."); });
这样做但我想避免为每个模型创建’BasicValidation’.
解决方法
在我之前的回答中,我误解了这个问题.主要目标是避免不同验证器中的代码重复.经过一番调查,我找到了符合您要求的解决方案.假设你有模特:
public abstract class BaseModel { public string BaseProperty1 { get; set; } public string BaseProperty2 { get; set; } } public class ChildModel : BaseModel { public int IdOfSthInDb { get; set; } }
您必须为基本模型创建验证器(它将被进一步使用):
class InternalBaseModelValidator : AbstractValidator<BaseModel> { public InternalBaseModelValidator() { RuleFor(x => x.BaseProperty1).NotEmpty().WithMessage("Property 1 is empty"); RuleFor(x => x.BaseProperty2).NotEmpty().WithMessage("Property 2 is empty"); } }
然后,您可以使用FluentValidation的新功能,称为PreValidate:
public class BaseModelValidator<T>: AbstractValidator<T> where T : BaseModel { // necessary for reusing base rules private readonly InternalBaseModelValidator preValidator; protected BaseModelValidator() { preValidator = new InternalBaseModelValidator(); } protected override bool PreValidate(ValidationContext<T> context,ValidationResult result) { var preValidationResult = preValidator.Validate(context.InstanceToValidate); if (preValidationResult.IsValid) { return true; } foreach(var error in preValidationResult.Errors) { result.Errors.Add(new ValidationFailure(error.PropertyName,error.ErrorMessage,error.AttemptedValue)); } return false; } }
为所有基础模型创建验证器后,您可以从它继承以进行ChildModel验证:
public class ChildModelValidator : BaseModelValidator<ChildModel> { public ChildModelValidator() : base() { RuleFor(x => x.IdOfSthInDb) .MustAsync(ItemMustExists) .WithMessage("Item does not exist."); } private Task<bool> ItemMustExists(int arg1,CancellationToken arg2) { return Task.FromResult(false); // some logic here } }
而已!