2012-02-20 18 views
7

Tengo modelo:reglas de validación personalizadas validación Fluido

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

y validadores para el modelo:

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

tengo fábrica validador, que debe resolver la dependencia:

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

tengo IUserService, que tiene los métodos IsUsernameUnique(string name) e IsEmailUnique (cadena de correo electrónico) `y desea usarlo en mi val clase de idator (el modelo debe ser válido solo si tiene un nombre de usuario y correo electrónico únicos).

  1. cómo utilizar mi servicio para la validación?
  2. ¿es posible registrar varias reglas de expresión regular con diferentes mensajes de error? ¿Funcionará en el lado del cliente? (Si no, ¿cómo crear una lógica de validación personalizada para él?)
  3. la validación en el servidor funcionará automáticamente antes del método de paso de modelo en acción, y es suficiente para llamar a la propiedad ModelState.IsValid, o tengo que hacer algo más ? ACTUALIZACIÓN
  4. ¿es posible acceder a todas las propiedades del modelo cuando se valida alguna propiedad? (Por ejemplo, quiero comparar contraseña y cuando ConfirmPassword registro)

Respuesta

21

1) cómo usar mi servicio para la validación?

usted podría utilizar la regla Must:

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

2) ¿es posible registrar varias reglas de expresiones regulares con diferentes mensajes de error? ¿Funcionará en el lado del cliente? (Si no, cómo crear la lógica de validación personalizado para ello?)

No, sólo puede tener un tipo de validación por propiedad

si no, cómo crear la lógica de validación personalizado para ello?

Usted podría utilizar la regla debe:

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

3) es la validación en el lado del servidor funcionará automáticamente antes de que pase modelo en el método de acción, y es suficiente para llamar a la propiedad ModelState.IsValid, o tengo que hacer algo mas?

Sí, absolutamente.Su acción del controlador podría tener este aspecto:

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

ACTUALIZACIÓN:

4) es posible acceder a todas las propiedades de modelo cuando validar alguna propiedad? (Por ejemplo, quiero comparar contraseña y ConfirmPassword cuando registro)

Sí, por supuesto:

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

Acerca de 2: quiero tener mu ltiples expresiones regulares y cada expresión regular tiene su propio mensaje de error. ¿Es posible? –

+0

@EvgenyLevin, ya he cubierto esto en mi respuesta: 'No, solo puede tener un tipo de validación por propiedad'. De modo que tiene 2 posibilidades: ya sea que se le ocurra una sola expresión regular que pueda validar todo o use la regla Debe para escribir alguna lógica personalizada. –

+0

y no puedo escribir más de uno. ¿Las reglas para la lógica personalizada también? Por favor mira la actualización (punto 4). –

4

una variante más agradable es utilizar 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; 
    } 

De esta manera se se vuelve trivial de usar:

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

Gracias por su respuesta. –

Cuestiones relacionadas