32 votes

ASP.NET MVC 2 - Html.DropDownListFor confusion avec ViewModel

Je suis totalement perdu et confus sur la façon d'utiliser le nouveau fortement typé Html.DropDownListFor d'aide sur le ASP.NET MVC 2.0 R2

Dans le point de Vue, je suis d'écriture:

<%= Html.DropDownListFor(m => m.ParentCategory, new SelectList(Model.Categories, "CategoryId", "Name", Model.ParentCategory), "[ None ]")%>

<%= Html.ValidationMessageFor(m => m.ParentCategory)%>

et mon Modèle objet est donc:

public class CategoryForm : FormModelBase
{
    public CategoryForm()
    {
        Categories = new List<Category>();

        Categories.Add(new CategoryForm.Category() {
                           CategoryId = 1, 
                           Name = "CPUs" });
        Categories.Add(new CategoryForm.Category() { 
                           CategoryId = 2, 
                           Name = "Memory" });
        Categories.Add(new CategoryForm.Category() { 
                           CategoryId = 3, 
                           Name = "Hard drives" });
    }

    // ...other props, snip... //

    public Category ParentCategory { get; set; }

    public IList<Category> Categories { get; protected set; }

    public class Category
    {
        public int? CategoryId { get; set; }
        public string Name { get; set; }
    }
}

Le problème est que lorsque je sélectionne un élément dans la liste déroulante, de dire le premier point, j'ai le ValidationMessageFor d'erreur "La valeur '1' n'est pas valide."

J'ai donc changer la Vue...

<%= Html.DropDownListFor(m => m.ParentCategory.**CategoryId**, 
                              new SelectList .../ snip  ) %>

Maintenant, il fonctionne un peu comme ça. Le ParentCategory bien dans mon ViewModel est défini avec la bonne "CategoryId", mais le " Nom " est NULL. Suis-je mieux d'avoir un nullable int pour ParentCategory propriété au lieu d'un typage fort "Catégorie" de l'objet?

28voto

Rami A. Points 3207

J'ai été également rencontrent le même problème.

Quand je debug de l'Action et de regarder la ModelState.Valeurs[1].Erreurs[0].Exception par exemple, je vois le suivant:

{"Le paramètre de conversion de type 'System.Chaîne' de type 'System.Les Collections.Génériques.KeyValuePair`2[[Système.Chaîne, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[Système.Int64, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]' a échoué car aucun type de convertisseur peut convertir entre ces types."} Système.Exception {Système.InvalidOperationException}

Dans mon scénario, mon SelectList est créé à partir d'un Dictionnaire et je l'utilise dans mon point de vue:

<%=Html.DropDownListFor(x => x.MyDictionary, 
                             new SelectList(
                                 Model.MyDictionary, 
                                 "Value", 
                                 "Key")) %>

Quand je l'ai changé pour:

<%=Html.DropDownListFor(x => x.MyDictionary.Keys, // <-- changed to .Keys
                             new SelectList(
                                 Model.MyDictionary, 
                                 "Value", 
                                 "Key")) %>

Il a fonctionné sans problèmes.

Je vous remercie.

9voto

Edmon Points 91
 <%= Html.DropDownListFor(m => m.ParentCategory, 
                              new SelectList(
                                  Model.Categories,
                                  "CategoryId", 
                                  "Name",
                                  Model.ParentCategory),
                             "[ None ]")%> 
 

Avez-vous essayé d'utiliser Model.ParentCategory.CategoryId comme dernier paramètre dans SelectList et supprimer le paramètre [None] ?

8voto

Je me débarrasserais de

 public Category ParentCategory { get; set; }
 

et faire un

 public int? CategoryId { get; set; }
 

au lieu. De toute façon, vous n'avez probablement besoin que de l'identifiant - vous pouvez toujours rechercher l'objet réel en utilisant l'identifiant comme clé (en utilisant un linq / lambda sur votre liste dans votre cas).

La vue aura alors ces deux:

 <%= Html.DropDownListFor(m => m.CategoryId, 
                              new SelectList(
                                  Model.Categories, 
                                  "CategoryId", 
                                  "Name", 
                                  Model.CategoryId), 
                              "[ None ]")%>

<%= Html.ValidationMessageFor(m => m.CategoryId)%>
 

1voto

Gertjan Points 51

Si le SelectList est null dans le ViewModel, j'ai aussi reçu l'erreur ci-dessus

Assurez-vous que la liste de sélection est définie

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X