2012-02-20 13 views
7

Ho modello:regole di convalida convalida personalizzati Fluent

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

E validatore per il modello:

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."); 
    } 
} 

ho fabbrica di convalida, che dovrebbe risolvere la dipendenza:

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

ho IUserService, che ha metodi IsUsernameUnique(string name) e IsEmailUnique (string email) `e voglio usarlo nella mia val classe idator (il modello dovrebbe essere valido solo se ha un nome utente e una e-mail univoci).

  1. come utilizzare il servizio per la convalida?
  2. è possibile registrare più regole di espressione regolare con diversi messaggi di errore? funzionerà sul lato client? (se no, come creare una logica di convalida personalizzata per questo?)
  3. è la convalida sul lato server funzionerà automaticamente prima del metodo pass in action, ed è sufficiente chiamare la proprietà ModelState.IsValid, oppure devo fare qualcosa di più ? UPDATE
  4. è possibile accedere a tutte le proprietà del modello quando si convalidano alcune proprietà? (Per esempio voglio mettere a confronto Password e ConfirmPassword quando il registro)

risposta

21

1) come utilizzare il mio servizio per la convalida?

è possibile utilizzare il Must regola:

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

2) è possibile registrare più regole per le espressioni regolari con diversi messaggi di errore? funzionerà sul lato client? (Se no, come creare la logica di convalida personalizzato per questo?)

No, si può avere un solo tipo di convalida per immobile

se non, come creare la logica di convalida personalizzata per esso?

Si potrebbe utilizzare la regola deve:

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

3) è la convalida sul lato server funzionerà automaticamente prima passaggio modello metodo di azione, ed è sufficiente per chiamare immobili ModelState.IsValid, o devo fare qualcosa di più?

Sì, assolutamente.La vostra azione di controllo potrebbe essere la seguente:

[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) è possibile accedere a tutte le proprietà del modello quando convalidare alcune proprietà? (Per esempio voglio mettere a confronto Password e ConfirmPassword quando il registro)

Sì, certo:

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

Circa 2: voglio avere mu piccole espressioni regolari e ogni regexp ha il proprio messaggio di errore. È possibile? –

+0

@EvgenyLevin, ho già trattato questo aspetto nella mia risposta: "No, puoi avere solo un tipo di convalida per proprietà". Quindi hai 2 possibilità: o trovare una singola regex che possa validare tutto o usare la regola Must per scrivere una logica personalizzata. –

+0

e non posso scrivere più di una. Anche le regole per la logica personalizzata? Si prega di guardare l'aggiornamento (punto 4). –

4

una variante più bello è quello di utilizzare un 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; 
    } 

In questo modo diventa banale da usare:

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

Grazie per la risposta. –

Problemi correlati