ASP.NET MVC 2 - Html.DropDownList для путаницы с ViewModel - PullRequest
32 голосов
/ 21 февраля 2010

Я полностью теряюсь и путаюсь в том, как использовать новый строго типизированный помощник Html.DropDownListFor для ASP.NET MVC 2.0 R2

В представлении, которое я пишу:

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

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

и мой объект Model таков:

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

Проблема в том, что когда я выбираю элемент из выпадающего списка, скажем, первый элемент, я получаю следующее сообщение ValidationMessageFor error "Значение '1' недопустимо."

Так что я изменил вид на ...

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

Теперь это работает, вроде. Свойство ParentCategory в моей ViewModel имеет правильный «CategoryId», но «Name» равно NULL. Мне лучше иметь просто обнуляемое int для свойства ParentCategory вместо строго типизированного объекта Category?

Ответы [ 4 ]

29 голосов
/ 05 марта 2010

У меня тоже была такая же проблема.

Когда я отлаживаю Action и смотрю на ModelState.Values ​​[1] .Errors [0]. Исключение, например, я вижу следующее:

{"Преобразование параметра из типа 'System.String' в тип 'System.Collections.Generic.KeyValuePair`2 [[System.String, mscorlib, Версия = 2.0.0.0, Culture = нейтральный, PublicKeyToken = b77a5c561934e089], [System.Int64, mscorlib, версия = 2.0.0.0, культура = нейтральная, PublicKeyToken = b77a5c561934e089]] 'не удалось, поскольку преобразователь типов не может преобразовать эти типы в другие. "} System.Exception {System.InvalidOperationException}

В моем сценарии мой список SelectList создается из словаря, и я использую его в моем представлении:

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

Когда я изменил его на:

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

Работало без проблем.

Спасибо.

9 голосов
/ 05 апреля 2010
<%= Html.DropDownListFor(m => m.ParentCategory, 
                              new SelectList(
                                  Model.Categories,
                                  "CategoryId", 
                                  "Name",
                                  Model.ParentCategory),
                             "[ None ]")%> 

Вы пытались использовать Model.ParentCategory.CategoryId в качестве последнего параметра в SelectList и удалить [None] параметр?

8 голосов
/ 08 сентября 2010

Я бы избавился от

public Category ParentCategory { get; set; }

и сделать

public int? CategoryId { get; set; }

вместо этого. В любом случае вам, вероятно, нужен только Id - вы всегда можете найти фактический объект, используя Id в качестве ключа (используя linq / lambda в вашем списке в вашем случае).

Представление будет иметь следующие два значения:

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

<%= Html.ValidationMessageFor(m => m.CategoryId)%>
1 голос
/ 30 ноября 2012

Если SelectList является нулевым в ViewModel, я также получил вышеупомянутую ошибку

Убедитесь, что SelectList установлен

...