FluentValidation Call RuleSet and General 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'm trying to do is invoke validation using correctness, but I also want to return the "general" rules when I invoke validation using a RuleSet.

The code that I am for invoking the verification 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 CallValidation method with the CallValidation element, but it also does not call the "general" rules.

I know that I can create a โ€œCommonโ€ RuleSet to run these rules, but in this case I would always have to invoke a check using the Common RuleSet.

Is it possible to call RuleSet, as well as call the general rules.

+6
source share
3 answers

I found one way to do this by adding a second validator.Validate to the CallValidation(string ruleSet) method, it looks like this

 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
source

Instead, you can do this:

 FluentValidation.Results.ValidationResult resultCommon = validator.Validate(parameter, Ruleset : "default, Insert"); 
+7
source

In your Validator class, create a method that includes all the โ€œgeneralโ€ rules that you must apply at any time. Now you can call this method

  • from your "create" RuleSet
  • outside 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 a RuleSet for action in the controller

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

This ensures that requests to the Create action are validated using the RuleSet Create. All other actions will use the ExecuteCommonRules call in the controller.

+6
source

All Articles