2010-06-22 4 views
0

J'ai un formulaire avec une liste déroulante rendue en utilisant Html.DropDownListFor(...). Le champ de modèle de vue qui correspond à la liste déroulante est associé à un attribut [Required(...)]. Cela fonctionne correctement sur ma machine locale, mais dès que je publie sur notre serveur de développement, les listes déroulantes affichent le message d'erreur requis, même lorsqu'une valeur est sélectionnée dans la liste. Cela se produit uniquement dans IE - Firefox soumet très bien.La validation ASP.NET MVC2 ne fonctionne pas avec la liste déroulante dans IE <8

Des pensées?

Code pertinent

Vue:

<ol class="form"> 
    <li> 
     <%= Html.LabelFor(x => x.ContactTitle) %> 
     <%= Html.DropDownListFor(x=>x.ContactTitle, Model.GetTitleOptions()) %> 
     <%= Html.ValidationMessageFor(x => x.ContactTitle) %> 
    </li> 
    <!-- more fields... --> 
</ol> 

Voir Modèle:

[Required(ErrorMessage = "Title is required")] 
[DisplayName("Title")] 
public string ContactTitle { get; set; } 

// ... 

public SelectList GetTitleOptions() 
{ 
    return new SelectList(new string[] 
    { 
     "","Dr.", "Mr.", "Ms.", "Mrs.", "Miss" 
    }); 
} 

C'est des choses assez basique ... Je suis à une perte. Edit: Juste découvert ce bug est limité à la vue de compatibilité IE 8 (et peut-être des versions antérieures). IE 8 en mode standard fonctionne comme prévu ...

Répondre

2

Craie celui-ci jusqu'à la stupidité. Le code dans l'exemple produit une sortie similaire à ce qui suit:

<select> 
    <option></option> 
    <option>Dr.</option> 
    <option>Mr.</option> 
    <option>Ms.</option> 
    <option>Mrs.</option> 
    <option>Miss</option> 
</select> 

Et la fonction de validation MVC pertinente (lorsqu'un RequiredAttribute est appliqué à une propriété qui correspond à une liste déroulante) est la suivante:

Sys.Mvc.RequiredValidator._validateSelectInput = function Sys_Mvc_RequiredValidator$_validateSelectInput(optionElements) { 
    /// <param name="optionElements" type="DOMElementCollection"> 
    /// </param> 
    /// <returns type="Object"></returns> 
    for (var i = 0; i < optionElements.length; i++) { 
     var element = optionElements[i]; 
     if (element.selected) { 
      if (!Sys.Mvc._validationUtil.stringIsNullOrEmpty(element.value)) { 
       return true; 
      } 
     } 
    } 
    return false; 
} 

Notez que la fonction vérifie element.value. Dans le cas du html ci-dessus, l'attribut value est vide car il n'y a aucun attribut de valeur sur les éléments d'option. Par conséquent, la fonction de validation renvoie false et l'erreur se produit. Cela semble se produire uniquement dans IE < 8, vraisemblablement parce que d'autres navigateurs affectent par défaut le texte d'un élément d'option à l'attribut value si aucun n'est spécifié.

La solution était de modifier la façon dont je retournais les éléments de la liste de sélection à partir de laquelle la liste déroulante a été construite comme ceci:

public IEnumerable<SelectListItem> GetTitleOptions() 
{ 
    return BuildSelectListItems(new string[] 
    { 
     "","Dr.", "Mr.", "Ms.", "Mrs.", "Miss" 
    }); 
} 

private List<SelectListItem> BuildSelectListItems(IEnumerable<string> values) { 
    return (from v in values 
      select new SelectListItem() 
      { 
       Text = v, 
       Value = v 
      }).ToList(); 
} 

Il en résulte la sortie HTML beaucoup plus prévisible:

<select> 
    <option value=""></option> 
    <option value="Dr.">Dr.</option> 
    <option value="Mr.">Mr.</option> 
    <option value="Ms.">Ms.</option> 
    <option value="Mrs.">Mrs.</option> 
    <option value="Miss">Miss</option> 
</select> 

ce qui bien sûr la fonction valide correctement.

Questions connexes