加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c# – FluentValidation – 预验证/条件验证,无代码重复

发布时间:2020-12-15 07:51:06 所属栏目:百科 来源:网络整理
导读:我正在尝试创建验证,它可以有两个组并在第一次失败时阻止第二次验证(它包含许多规则). 现在我确实在内部和’main validator’中创建了一个私有的’BasicValidation’类,如下所示: RuleFor(m = m).SetValidator(new BasicValidation()).DependentRules(() =
我正在尝试创建验证,它可以有两个组并在第一次失败时阻止第二次验证(它包含许多规则).

现在我确实在内部和’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
    }
}

而已!

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读