Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MVC 2 DropDownList not selecting value in case of List

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?

like image 617
Michiel De Jong Avatar asked Oct 17 '25 05:10

Michiel De Jong


1 Answers

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.

like image 105
Darin Dimitrov Avatar answered Oct 18 '25 20:10

Darin Dimitrov



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!