FluentValidation调用RuleSet和Common Rules

Qpi*_*ate 9 c# fluentvalidation

我有以下课程

public class ValidProjectHeader : AbstractValidator<Projects.ProjectHeader>
    {
        public ValidProjectHeader()
        {

            RuleFor(x => x.LobId).Must(ValidateLOBIDExists);
            RuleFor(x => x.CreatedByUserId).NotEmpty();
            RuleFor(x => x.ProjectManagerId).NotEmpty();
            RuleFor(x => x.ProjectName).NotEmpty();
            RuleFor(x => x.SalesRepId).NotEmpty();
            RuleFor(x => x.DeliveryDate).NotEmpty();
            RuleFor(x => x.ProjectStatusId).NotEmpty();
            RuleFor(x => x.DeptartmentId).NotEmpty();
            RuleFor(x => x.CustomerId).NotEmpty();

            RuleSet("Insert", () =>
            {
                RuleFor(x => x.ProjectLines).Must(ValidateProjectLines).SetCollectionValidator(new ValidProjectLine());
            });
            RuleSet("Update", () =>
            {
                RuleFor(x => x.ProjectLines).SetCollectionValidator(new ValidProjectLine());
            });


        }
Run Code Online (Sandbox Code Playgroud)

我想要做的是用rulset调用验证,但我还想在使用RuleSet调用验证时返回"常用"规则.

我调用验证的代码如下

public abstract class BaseValidator
    {
        private List<ValidationFailure> _errors;
        public bool IsValid { get; protected set; }
        public List<ValidationFailure> Errors
        {
            get { return _errors; }
            protected set { _errors = value; }
        }
        public virtual bool CallValidation()
        {
            Errors = new List<ValidationFailure>();
            ValidatorAttribute val = this.GetType().GetCustomAttributes(typeof(ValidatorAttribute), true)[0] as ValidatorAttribute;
            IValidator validator = Activator.CreateInstance(val.ValidatorType) as IValidator;
            FluentValidation.Results.ValidationResult result = validator.Validate(this);
            IsValid = result.IsValid;
            Errors = result.Errors.ToList();
            return result.IsValid;
        }

        public virtual bool CallValidation(string ruleSet)
        {
            Errors = new List<ValidationFailure>();
            ValidatorAttribute val = this.GetType().GetCustomAttributes(typeof(ValidatorAttribute), true)[0] as ValidatorAttribute;
            IValidator validator = Activator.CreateInstance(val.ValidatorType) as IValidator;
            FluentValidation.Results.ValidationResult result = validator.Validate(new FluentValidation.ValidationContext(this, new PropertyChain(), new RulesetValidatorSelector(ruleSet)));
            IsValid = result.IsValid;
            Errors = result.Errors.ToList();
            return result.IsValid;
        }

        public BaseValidator()
        {
            Errors = new List<ValidationFailure>();
        }
    }
Run Code Online (Sandbox Code Playgroud)

我可以CallValidation用成员调用方法,ruleSet但它也没有调用"常用"规则.

我知道我可以为运行这些规则创建一个"Common"RuleSet,但在这种情况下,我必须始终使用Common RuleSet调用验证.

有什么方法可以调用RuleSet并调用通用规则.

小智 15

相反,你可以这样做:

using FluentValidation;
...
FluentValidation.Results.ValidationResult resultCommon =
    validator.Validate(parameter, ruleSet: "default, Insert");
Run Code Online (Sandbox Code Playgroud)

using指令需要将Validate()扩展方法从DefaultValidatorExtensions具有该ruleSet属性的范围中引入.否则,您将只有Validate()继承可用的方法AbstractValidator<T>,该方法没有ruleSet参数.


Nas*_*ser 10

在Validator类中创建一个方法,该方法包括需要始终应用的所有"常用"规则.现在你可以调用这个方法

  • 从你的"创建"RuleSet
  • 来自RuleSet之外

public class MyEntityValidator : AbstractValidator<MyEntity>
{
    public MyEntityValidator()
    {
        RuleSet("Create", () =>
            {
                RuleFor(x => x.Email).EmailAddress();
                ExecuteCommonRules();
            });

        ExecuteCommonRules();
    }

    /// <summary>
    /// Rules that should be applied at all times
    /// </summary>
    private void ExecuteCommonRules()
    {
        RuleFor(x => x.Name).NotEmpty();
        RuleFor(x => x.City).NotEmpty();
    }
}
Run Code Online (Sandbox Code Playgroud)

您可以为控制器中的操作定义RuleSet

[HttpPost]
public ActionResult Create([CustomizeValidator(RuleSet = "Create")]  MyEntity model)
Run Code Online (Sandbox Code Playgroud)

这将确保将使用RuleSet Create验证对操作Create的请求.所有其他操作将使用对控制器中的ExecuteCommonRules的调用.