FluentValidation调用RuleSet和Common Rules

时间:2012-12-14 10:52:17

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


        }

我想要做的是用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>();
        }
    }

我可以使用成员CallValidation调用方法ruleSet,但它也不会调用“常用”规则。

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

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

5 个答案:

答案 0 :(得分:12)

相反,你可以这样做:

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

using指令需要将Validate()扩展方法从DefaultValidatorExtensions纳入具有ruleSet属性的范围。否则,您只能通过继承Validate()获得AbstractValidator<T>方法,而ruleSet方法没有{{1}}参数。

答案 1 :(得分:8)

在您的Validator类中创建一个方法,其中包括所有&#34; common&#34;需要始终应用的规则。现在你可以调用这个方法

  • 来自您的&#34;创建&#34;规则集
  • 来自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();
    }
}

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

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

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

答案 2 :(得分:3)

通过添加第二个validator.Validate,我找到了一种方法 CallValidation(string ruleSet)方法如下

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

答案 3 :(得分:0)

我刚刚在下面尝试过,并且有效

$ VAR1=1.1234-g13ab57737123
$ echo $VAR1 | grep -o "[0-9]\+\.[0-9]\+"
1.1234

答案 4 :(得分:0)

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