2012-12-14 22 views
6

Mam następujące klasyFluentValidation połączeń zestawu reguł i wspólnych reguł

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


     } 

i co próbuję zrobić, to zadzwonić do walidacji z rulset ale także chcą wrócić „wspólne” reguły kiedy nazywam sprawdzanie poprawności za pomocą zestawu reguł.

kod mam na wywołanie walidacji jest następujący

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

mogę wywołać metodę CallValidation z członem ruleSet ale nie jest to wywołanie „wspólne” reguły również.

Wiem, że mogę utworzyć "Common" RuleSet do uruchamiania tych reguł, ale w takim przypadku musiałbym zawsze wywoływać sprawdzanie poprawności za pomocą Common RuleSet.

Czy istnieje sposób, w jaki można wywołać zestaw reguł, a także wywołać wspólne reguły.

Odpowiedz

3

Znalazłem jeden sposób, aby to zrobić poprzez dodanie drugiego validator.Validate metody CallValidation(string ruleSet) się następująco

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

Zamiast tego można to zrobić:

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

Ta opcja prawdopodobnie nie istniała w kodzie źródłowym git od co najmniej 2009 r., Co doprowadziło mnie tutaj, ponieważ dokumentacja jest niepoprawna. – john

+0

Świetna rada! W FluentValidation 6.2.1 przypadek argumentu RuleSet jest inny: "ruleSet:" zamiast "Ruleset:". Przykład: validator.Validate (obj, ruleSet: "default, Insert"); –

6

W swojej klasie Validator stworzyć metodę, która zawiera wszystkie "wspólne" reguły, które muszą być stosowane przez cały czas. Teraz można wywołać tej metody

  • z „Utwórz” zestaw reguł
  • spoza zestawu reguł

Przykład

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

zdefiniować zestaw reguł dla działań w kontrolerze

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

Pozwoli to upewnić się, że żądania do działania Utwórz zostaną zatwierdzone przy użyciu funkcji Utwórz zestaw. Wszystkie inne działania będą używać wywołania ExecuteCommonRules w kontrolerze.

Powiązane problemy