2011-05-20 21 views
20

¿Cómo me gustaría tener varios cuadros de texto en un formulario MVC 3 tratados como uno para fines de validación?MVC Validación de formulario en varios campos

Es un campo de número de teléfono simple con un cuadro de texto para el código de área, uno para el prefijo y otro para los últimos cuatro dígitos.

En realidad, hay dos criterios de validación:

1) Están todos los necesarios. 2) Todos deben contener números enteros.

Ahora, esto es simple cuando lo hace para campos individuales, pero ¿cómo puedo crear el equivalente de un Visual.Validator personalizado de ASP.NET con MVC para que pueda validar los tres campos como un todo?

+2

Mi comentario no se refiere a su pregunta de validación, pero me pregunto si este es el mejor interfaz de usuario para usar para la entrada del número de teléfono. ¿No es este diseño más trabajo para el usuario; tab-tabing entre los cuadros de texto, más trabajo si quieren pegar un número de teléfono o eliminar un número de teléfono ya ingresado. Pensé que un solo cuadro de texto con validación basada en expresiones regulares sería más habitual. –

+1

Si tomara decisiones, diría que tiene razón, pero por alguna razón alguien decidió que deben ser tres cuadros de texto. No preguntes :) – Scott

+0

Ouch. ¿Puede influir en su opinión con los ejemplos que he citado? Además, supongo que no es necesario que ninguna persona no estadounidense ingrese sus números de teléfono en este sistema ... ya que los nuestros a menudo tienen un formato diferente. –

Respuesta

20

verdad es que acabé la implementación de una costumbre ValidationAttribute para resolver esto, usando el mismo tipo de lógica se presenta en CompareAttribute que le permite utilizar la reflexión para evaluar los valores de otras propiedades. Esto me permitió poner en práctica esta en el nivel de propiedad en lugar del nivel de modelo y también permite la validación del lado del cliente a través de JavaScript discreta:

public class MultiFieldRequiredAttribute : ValidationAttribute, IClientValidatable 
    { 
     private readonly string[] _fields; 

     public MultiFieldRequiredAttribute(string[] fields) 
     { 
      _fields = fields; 
     } 

     protected override ValidationResult IsValid(object value, ValidationContext validationContext) 
     { 
      foreach (string field in _fields) 
      { 
       PropertyInfo property = validationContext.ObjectType.GetProperty(field); 
       if (property == null) 
        return new ValidationResult(string.Format("Property '{0}' is undefined.", field)); 

       var fieldValue = property.GetValue(validationContext.ObjectInstance, null); 

       if (fieldValue == null || String.IsNullOrEmpty(fieldValue.ToString())) 
        return new ValidationResult(this.FormatErrorMessage(validationContext.DisplayName)); 
      } 

      return null; 
     } 

     public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context) 
     { 
      yield return new ModelClientValidationRule 
      { 
       ErrorMessage = this.ErrorMessage, 
       ValidationType = "multifield" 
      }; 
     } 
    } 
+0

Tuve que cambiar el ValidationType a "required" para tener un trabajo de validación del lado del cliente. Encontré esta respuesta (http://stackoverflow.com/questions/13740489/valid-values-for-modelclientvalidationrule-validationtype-string) para ser útil con los valores aceptados ValidationType. – gmasselli

17

Puede manejar esto poniendo IValidatableObject en la clase de modelo e implementando el método Validate.

Podría ser algo como esto:

public IEnumerable<ValidationResult> Validate(ValidationContext validationContext) 
{ 
     if (String.IsNullOrEmpty(_PhonePart1) || String.IsNullOrEmpty(_PhonePart2) 
      || String.IsNullOrEmpty(_PhonePart3)) 
     { 
      yield return new ValidationResult("You must enter all " + 
        "three parts of the number."); 
     } 

} 
1

Scott, está usando un aglomerante modelo personalizado dentro de su alcance? De ser así, puede implementar un IModelBinder para combinar los resultados de los tres campos de texto en un único campo de número de teléfono, que puede decorarse con atributos de validación. He aquí una pregunta StackOverflow que tiene un ejemplo de cómo hacer esto: DataAnnotation Validations and Custom ModelBinder

Cuestiones relacionadas