2012-02-20 17 views
7

mam model:Zaawansowany niestandardowych walidacji zasady walidacji

[Validator(typeof(RegisterValidator))] 
public class RegisterModel 
{ 
    public string Name { get; set; } 

    public string Email { get; set; } 

    public string Password { get; set; } 

    public string ListOfCategoriess { get; set; } 
} 

I validator dla modelu

public class RegisterValidator:AbstractValidator<RegisterModel> 
{ 
    public RegisterValidator(IUserService userService) 
    { 
     RuleFor(x => x.Name).NotEmpty().WithMessage("User name is required."); 
     RuleFor(x => x.Email).NotEmpty().WithMessage("Email is required."); 
     RuleFor(x => x.Email).EmailAddress().WithMessage("Invalid email format."); 
     RuleFor(x => x.Password).NotEmpty().WithMessage("Password is required."); 
     RuleFor(x => x.ConfirmPassword).NotEmpty().WithMessage("Please confirm your password."); 
    } 
} 

mam fabrykę validator, który powinien rozwiązać zależność:

public class WindsorValidatorFactory : ValidatorFactoryBase 
{ 
    private readonly IKernel kernel; 

    public WindsorValidatorFactory(IKernel kernel) 
    { 
     this.kernel = kernel; 
    } 

    public override IValidator CreateInstance(Type validatorType) 
    { 
     if (validatorType == null) 
      throw new Exception("Validator type not found."); 
     return (IValidator) kernel.Resolve(validatorType); 
    } 
} 

mam IUserService, który ma metody IsUsernameUnique(string name) i IsEmailUnique (string e-mail) `i chce go użyć w moim val klasa idator (model powinien być ważny tylko wtedy, gdy ma unikalną nazwę użytkownika i adres e-mail).

  1. Jak używać mojej usługi do sprawdzania poprawności?
  2. Czy można zarejestrować wiele reguł wyrażeń regularnych z różnymi komunikatami o błędach? czy będzie działać po stronie klienta? (jeśli nie, jak utworzyć dla niego niestandardową logikę walidacji?)
  3. to sprawdzanie poprawności po stronie serwera będzie działało automatycznie przed metodą przekazania modelu w działaniu i wystarczy wywołać właściwość ModelState.IsValid lub muszę zrobić coś więcej ? UPDATE
  4. Czy możliwy jest dostęp do wszystkich właściwości modelu podczas sprawdzania poprawności niektórych właściwości? (Na przykład chcę porównać hasło i ConfirmPassword gdy rejestr)

Odpowiedz

21

1) w jaki sposób korzystać z usługi walidacji?

Mogłeś użyć Must zasadę:

RuleFor(x => x.Email) 
    .NotEmpty() 
    .WithMessage("Email is required.") 
    .EmailAddress() 
    .WithMessage("Invalid email format.") 
    .Must(userService.IsEmailUnique) 
    .WithMessage("Email already taken"); 

2) jest to możliwe, aby zarejestrować kilka regularnych reguły wyrażenia z różnych komunikatów o błędach? czy będzie działać po stronie klienta? (Jeśli nie, jak utworzyć niestandardową logikę walidacji dla niego?)

Nie można mieć tylko jeden rodzaj walidacji za nieruchomości

Jeśli nie, w jaki sposób tworzyć niestandardowe logiki walidacji dla niego?

Można użyć reguły muszą:

RuleFor(x => x.Password) 
    .Must(password => SomeMethodContainingCustomLogicThatMustReturnBoolean(password)) 
    .WithMessage("Sorry password didn't satisfy the custom logic"); 

3) jest walidacja po stronie serwera będzie pracować automatycznie przed modelu przejściu w sposobie działania, a to wystarczy, aby wywołać właściwość ModelState.IsValid, czy muszę zrobić coś więcej?

Tak, zdecydowanie.Twoje działanie kontrolera mógłby wyglądać następująco:

[HttpPost] 
public ActionResult Register(RegisterModel model) 
{ 
    if (!ModelState.IsValid) 
    { 
     // validation failed => redisplay the view so that the user 
     // can fix his errors 
     return View(model); 
    } 

    // at this stage the model is valid => process it 
    ... 
    return RedirectToAction("Success"); 
} 

UPDATE:

4) Czy to możliwe, aby uzyskać dostęp do wszystkich właściwości modelu Kiedy validate jakąś nieruchomość? (Na przykład chcę porównać hasło i ConfirmPassword gdy rejestr)

Tak, oczywiście:

RuleFor(x => x.ConfirmPassword) 
    .Equal(x => x.Password) 
    .WithMessage("Passwords do not match"); 
+0

O 2: chcę mieć mu Zmodyfikuj wyrażenie, a każdy regexp ma własny komunikat o błędzie. Czy to możliwe? –

+0

@EvgenyLevin, już to omówiłem w mojej odpowiedzi: "Nie, możesz mieć tylko jeden typ sprawdzania poprawności dla każdej właściwości". Masz więc dwie możliwości: albo wymyśl jedno wyrażenie, które może sprawdzić wszystko, albo użyj reguły Must, aby napisać niestandardową logikę. –

+0

i nie mogę zapisać więcej niż jednej. Czy reguły dla niestandardowej logiki też? Proszę spojrzeć na aktualizację (punkt 4). –

4

ładniejszy wariant jest użycie RuleBuilderExtension:

public static class RuleBuilderExtensions 
{ 
    public static IRuleBuilder<T, string> Password<T>(this IRuleBuilder<T, string> ruleBuilder, int minimumLength = 14) 
    { 
     var options = ruleBuilder 
      .NotEmpty().WithMessage(ErrorMessages.PasswordEmpty) 
      .MinimumLength(minimumLength).WithMessage(ErrorMessages.PasswordLength) 
      .Matches("[A-Z]").WithMessage(ErrorMessages.PasswordUppercaseLetter) 
      .Matches("[a-b]").WithMessage(ErrorMessages.PasswordLowercaseLetter) 
      .Matches("[0-9]").WithMessage(ErrorMessages.PasswordDigit) 
      .Matches("[^a-zA-Z0-9]").WithMessage(ErrorMessages.PasswordSpecialCharacter); 
     return options; 
    } 

W ten sposób jest trywialny w użyciu:

RuleFor(x => x.Password).Password(); 
+0

Dziękuję za odpowiedź. –