32

I'm getting totally lost and confused on how to use the new strongly typed Html.DropDownListFor helper on ASP.NET MVC 2.0 R2

In the View I'm writting:

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

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

and my Model object is thus:

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

The problem is that when I select an item from the dropdown list, say the first item, I get the following ValidationMessageFor error "The value '1' is invalid."

So I change the View to...

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

Now it works, kinda. The ParentCategory property in my ViewModel is set with the correct 'CategoryId' but the 'Name' is NULL. Am I better off just having a nullable int for ParentCategory property instead of a strongly typed 'Category' object?

1

4 Answers 4

29

I was also experiencing the same issue.

When I debug the Action and look at the ModelState.Values[1].Errors[0].Exception for example, I see the following:

{"The parameter conversion from type 'System.String' to type 'System.Collections.Generic.KeyValuePair`2[[System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[System.Int64, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]' failed because no type converter can convert between these types."} System.Exception {System.InvalidOperationException}

In my scenario, my SelectList is created from a Dictionary and i use this in my view:

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

When I changed it to:

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

It worked without issues.

Thank you.

Sign up to request clarification or add additional context in comments.

Comments

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

Did you try to use Model.ParentCategory.CategoryId as a last parameter in SelectList and remove [None] parameter?

1 Comment

wont replacing the "[ None ]" with the CategoryId only change the default/initial value of the drop down list and not the value in the viewmodel on postback? Was previously a downvote but I took it back in a fit of uncertainty after realising there is probably a different overload. Can you clarify a bit?
8

I would get rid of

public Category ParentCategory { get; set; }

and make a

public int? CategoryId { get; set; }

instead. You probably only need the Id anyways - you could always look up the actual object using the Id as key (using a linq/lambda on your list in your case).

The view will then have these two:

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

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

Comments

1

If the SelectList is null in the ViewModel I also received the above error

Make sure that the SelectList is set

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.