views:

1990

answers:

1

Why isn't modelbinding working on a DropDown?
What am I doing wrong?
To illustrate my problem, I did the following:

Created a new asp.net MVC project (beta1) Created the following class:

HomeViewData : ViewDataDictionary  
+List : SelectList

Added a viewdata to the HomeController class as following

Homecontroller: Controller
+HomeViewData vd = new HomeViewData

Added the folowing lines to my Home.Index() method

vd.list = new SelectList(new List<string>(){"test", "test1", "test2"});
return View("Index", vd);

And replicated the same method but with a different signature to catch postback calls

[AcceptVerps(HttpVerbs.Post)]
public ActionResult Index(HomeViewdata d)

Here I added a breakpoint to the first line of code.
Then I added the following code to my Index.aspx

<%Html.BeginForm();%>
    <%=Html.DropDownList("List")%>
<%Html.EndForm();%>

As a result, I get a page that has a nice dropdown with the values test, test1 and test2.
Then after selecting a value I press enter (didn't bother with a submit button) and see how my breakpoint halts the code. I check the value of the HomeViewData... NULL

If I do the same exercise but with a textbox for example, it all works fine...
--EDIT--
Things I tried since this post:

  • Adding a [Bind(Prefix="")] attribute to my action as suggested by Phil
  • Adding a [Bind(Prefix=" ")] to see if this would remove the error of "empty name not allowed"
  • Adding the name of my action's parameter in my control's name
    <%=Html.DropDownList("d.List")%>
+2  A: 

Ah, the problem here is that by convention, the model binder is looking for values in the form of "d.PropertyName" because the argument to your Index action method is "d".

Since you could have multiple arguments to an action method, we use the argument name as the prefix by default.

Fixing this is easy, just use the Bind attribute to tell MVC not to use a prefix.

[AcceptVerps(HttpVerbs.Post)]
public ActionResult Index([Bind(Prefix="")]HomeViewdata d)
Haacked
Phil, today I tested your answer on my demo page. I received an error that the name cannot be null. So I changed the bind attribute to [Bind(Prefix="")]Now it works without error, but also with the same result as what I started with.
borisCallens
I think the SO parser removes spaces from between quotes in comments. So it should be [Bind(Prefix="[aSpace]")]
borisCallens
Then I tried it the other way round: I tried making the Html helper in my aspx page like this <%=Html.DropDownList("d.List"); but then I get the error that there is no such field to bind to.
borisCallens
If you make that change, you need to make sure that ViewData["d.List"] contains the items for the drop down list.
Haacked