MVC 2 DropDownList not selecting value in case of List
asp.net-mvc, c#, drop-down-menu, model-view-controller
Solution
That's a limitation of the `DropDownListFor` helper which is not able to extract the value from a complex lambda expression such as the one you are using (a lambda expression containing array index access). One possible workaround is the following:
<%= Html.DropDownListFor(
person => person.Addresses[i].State,
new SelectList(
Model.AvailableStates,
"Text",
"Value",
Model.Addresses[i].State
)
) %>
It's a bit ugly as we are now passing the same value in the SelectList constructor but this time the DropDownListFor helper will be able to properly set the corresponding option.
Problem
I am using ASP.Net MVC 2 and have trouble getting a DropDownList to bind properly. I am using a strongly typed ViewModel and the HTML.DropDownListFor statement to create the dropdown in my View. The statement works fine in the 'normal' scenario where I just bind the DropDown to a simple field in my ViewModel. I am having trouble using this scenario when my ViewModel contain a List (array) of multiple objects where I want a field in each of these objects to bind to a (seperate) DropDown. In that case the DropDown's do not get the correct initial value. For example the case where we have a person that can have multiple addresses. Each address consists of a Street, a City and a State. I want the state to be displayed as a DropDown. My model is: ``` public class PersonModel : CommonViewModel { public IList<SelectListItem> AvailableStates { get; set; } public string Name { get; set; } public IList<AddressModel> Addresses { get; set; } public PersonModel() { AvailableStates = GenerateStates(); } private IList<SelectListItem> GenerateStates() { List<SelectListItem> items = new List<SelectListItem>(); items.Add(new SelectListItem() { Text = "WA", Value = "WA" }); items.Add(new SelectListItem() { Text = "NY", Value = "NY" }); items.Add(new SelectListItem() { Text = "IH", Value = "IH" }); items.Add(new SelectListItem() { Text = "FL", Value = "FL" }); items.Add(new SelectListItem() { Text = "CA", Value = "CA" }); return items; } } public class AddressModel { public string Street { get; set; } public string City { get; set; } public string State { get; set; } } ``` Now in my View I want to use something like: ``` <% using (Html.BeginForm("SubmitPersonDetails", "Home", new { actionMode = "Person"}, FormMethod.Post, new { id = "SubmitPersonForm" })) {%> <div class="formrow longinput"> <%= Html.LabelFor(person => person.Name)%> <%= Html.TextBoxFor(person => person.Name)%> </div> <h4>Addresses</h4> <% for (int i = 0; i < Model.Addresses.Count; i++) { %> <div class="formrow"> <%= Html.TextBoxFor(person => person.Addresses[i].Street)%> <%= Html.TextBoxFor(person => person.Addresses[i].City)%> <%--<%= Html.TextBoxFor(person => person.Addresses[i].State)%>--%> <%= Html.DropDownListFor(person => person.Addresses[i].State, Model.AvailableStates) %> </div> <% } %> <input class="button primary" type="submit" value="Submit" name="Submit" /> <% } %> ``` For the Textboxes this works fine (also if I just use a textbox for State, see the commented out bit). The DropDown's are generated correctly but not set to the correct value. If I select a value in the DropDowns and submit the form the correct values are put back into my model. I also tried putting the Address part in a UserControl, which is then rendered several time. If I render the UserControl using Html.RenderPartial the correct values are set in the DropDOwn's but on Postback my model isn't populated correctly. If I render the UserControl using EditorFor I get the same problem as with the code above: the DropDown's don't get the correct initial value but on Postback I do get the selected values set in my model. Another thing I tried is making the Addresses not a List but instead hardcoding several addresses in my View Model (properties: Address1, Address2, Address3) and then using: <%= Html.DropDownListFor(person => person.Address1.State, Model.AvailableStates) %> In this case the DropDown does get the correct value. Obviously I don't want to use this workaround for lack of flexibility. What am I doing wrong? I am new to MVC so maybe it is my whole approach that is wrong?