简体   繁体   English

FluentValidation 调用规则集和通用规则

[英]FluentValidation Call RuleSet and Common Rules

I have the following class我有以下课程

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());
            });


        }

and what i am trying to do is call the validation with the rulset but i also want to return the "common" rules when i call the validation with the RuleSet.我正在尝试做的是使用 rulset 调用验证,但我也想在使用 RuleSet 调用验证时返回“通用”规则。

the Code I have for calling the validation is as follows我调用验证的代码如下

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>();
        }
    }

I can call the Method CallValidation with the member ruleSet but it is not calling the "common" rules also.我可以使用成员ruleSet调用方法CallValidation ,但它也不会调用“通用”规则。

I know I can create a "Common" RuleSet for running these rules but in that case i would have to call the validation with the Common RuleSet always.我知道我可以创建一个“通用”规则集来运行这些规则,但在那种情况下,我将不得不始终使用通用规则集调用验证。

Is there any way I can call the RuleSet and also call the common rules.有什么方法可以调用 RuleSet 并调用通用规则。

Instead you could do this:相反,您可以这样做:

using FluentValidation;
...
FluentValidation.Results.ValidationResult resultCommon =
    validator.Validate(parameter, ruleSet: "default, Insert");

The using directive is required to bring the Validate() extension method from DefaultValidatorExtensions into scope, which has the ruleSet property.需要using指令将Validate()扩展方法从DefaultValidatorExtensions引入范围,该范围具有ruleSet属性。 Otherwise you will only have the Validate() method available from inheriting AbstractValidator<T> , which doesn't have a ruleSet argument.否则,您将只能通过继承AbstractValidator<T>获得Validate()方法,它没有ruleSet参数。

In your Validator class create a method, that includes all "common" rules that need to be applied at all times.在您的 Validator 类中创建一个方法,其中包括需要始终应用的所有“通用”规则。 Now you can call this method现在你可以调用这个方法

  • from your "create" RuleSet从您的“创建”规则集中
  • from outside of the RuleSet来自规则集之外

Example例子

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();
    }
}

You define the RuleSet for an action in your controller您在控制器中为操作定义规则集

[HttpPost]
public ActionResult Create([CustomizeValidator(RuleSet = "Create")]  MyEntity model)

This will insure that requests to action Create will be validated with the RuleSet Create.这将确保对动作 Create 的请求将通过 RuleSet Create 进行验证。 All other action will use the call to ExecuteCommonRules in controller.所有其他操作将使用对控制器中 ExecuteCommonRules 的调用。

I have found one way to do it by adding a second validator.Validate to the CallValidation(string ruleSet) method it is as follows我找到了一种方法,通过向CallValidation(string ruleSet)方法添加第二个validator.Validate来实现,如下所示

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)));
            FluentValidation.Results.ValidationResult resultCommon = validator.Validate(this);
            IsValid = (result.IsValid && resultCommon.IsValid);
            Errors = result.Errors.Union(resultCommon.Errors).ToList();
            return IsValid;
        }

I just tried below and it works我刚刚在下面尝试过并且有效

   [CustomizeValidator(RuleSet = "default, Create")
    Fluent validation 10+ onwards.
      using FluentValidation;
     var validationResult = await 
     validator.ValidateAsync(account,options=>options("nameOfRuleSet"));

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM