5

La validación de mi longitud de cadena siempre falla en listas desplegables con un valor de cadena.MVC DropDownListFor y StringLength Attribute Not Playing Well juntos

Aquí es mi modelo:

[Required(ErrorMessage = "Required")] 
[StringLength(2, MinimumLength = 2)] 
[Display(Name = "Home Address State")] 
public string HomeAddressState { get; set; } 

Aquí es mi punto de vista:

@Html.DropDownListFor(model => model.HomeAddressState, new SelectList(ViewBag.States, "Value", "Text"), string.Empty) 
@Html.ValidationMessageFor(model => model.HomeAddressState) 

Aquí está la salida html:

<select data-val="true" data-val-length="The field Home Address State must be a string with a minimum length of 2 and a maximum length of 2." data-val-length-max="2" data-val-length-min="2" data-val-required="Required" id="HomeAddressState" name="HomeAddressState"><option value=""></option> 
<option value="CA">California</option> 
<option value="IL">Illinois</option> 
<option value="IN">Indiana</option> 
<option value="OH">Ohio</option> 
</select> 

No importa qué opción está seleccionada, el StringLength la validación falla en el lado del cliente. ¿Qué estoy haciendo incorrectamente?

+1

¿Por qué necesita la validación de StringLength para una lista desplegable? – Jesse

+1

presumiblemente porque su validación de modelo de datos es (correctamente) independiente de su vista de cliente. – bhamlin

+0

bhamlin es correcto. Yo uso [StringLength (2, MinimumLength = 2)] para crear correctamente el campo char (2) en mi base de datos ya que estoy usando código-primero. No quería ir con fluidez. –

Respuesta

0

porque StringLength coinciden con rangelength regla en jquery.validate. En el caso de una lista de selección, se comprobará el número de elementos seleccionados, no la longitud del valor seleccionado, de modo que si escribe una regla de longitud mínima de 1 funcionará

6

Aquí está el código de validación jquery relevante. Como puede ver, parece que aplica la validación de longitud al número de opciones seleccionadas, no a la longitud de la opción. Parece que solo se aplica a cajas de lista multiselección. Un poco extraño, para ser honesto.

maxlength: function(value, element, param) { 
    return this.optional(element) || this.getLength($.trim(value), element) <= param; 
} 

getLength: function(value, element) { 
    switch(element.nodeName.toLowerCase()) { 
     case 'select': 
      return $("option:selected", element).length; 
     case 'input': 
      if(this.checkable(element)) 
       return this.findByName(element.name).filter(':checked').length; 
    } 
    return value.length; 
} 

Lo que puede hacer es reemplazar la función getLength sí mismo para volver simplemente value.length directamente.

$.validator.prototype.getLength = function (value, element) { 
    return value.length; 
} 
+1

Gracias. ¿Dónde podría poner ese código? –

+0

En cualquier lugar después de incluir la biblioteca de validación de jquery. – bhamlin

+0

Eso es lo que pensé, pero no hay dados. El comportamiento predeterminado prevalece sobre mi anulación. Me pregunto cómo se crea una instancia de la biblioteca de validación. Parece que es una carga floja. En $ (document) .ready() pregunté $ .validator.methods.getLength y es nulo. –

2

para evitar romper la lógica de casillas de verificación y varias cajas de selección, se puede utilizar:

$.validator.prototype.getLength = function (value, element) { 
    switch (element.nodeName.toLowerCase()) { 
     case 'select': 
      { 
       var attr = $(this).attr('multiple'); 
       // For some browsers, `attr` is undefined; for others, 
       // `attr` is false. Check for both. 
       if (typeof attr !== 'undefined' && attr !== false) { 
        return $("option:selected", element).length; 
       } 
      } 
     case 'input': 
      if (this.checkable(element)) 
       return this.findByName(element.name).filter(':checked').length; 
    } 
    return value.length; 
} 

ADVERTENCIA: He probado esto sólo en DropDownFor, a fin de utilizar a su propio riesgo ....

Cuestiones relacionadas