Search code examples
c#asp.netasp.net-mvchtml-helperhtml.dropdownlistfor

ASP.NET MVC DropDownListFor doesn't set selected data to true in List


I have a view which has a model that is an IEnumerable. I use DropDownListFor Html helper in a foreach loop to output dropdown lists. But it doesn't set the selected item to true. Code as below:

@model IEnumerable<Example>
@foreach (var item in Model) {
    @Html.DropDownListFor(modelItem => item.FilePath, (IEnumerable<SelectListItem>)ViewBag.ConfigFiles, string.Empty, null)
}

The above code output a Html select element. But none of the options are selected even though the item.FilePath has the same value as one of the options.


Solution

  • This is an unfortunate limitation of using DropDownListFor() in a loop, and you need to generate a new SelectList in each iteration. However, your use of a foreach loop to generate the form controls will not work. Its creating duplicate name attributes which have no relationship to your model therefore will not bind, and its also generating duplicate id attributes which is invalid html.

    Change your model to IList<T> and use a for loop and generate a new SelectList in each iteration using the constructor that sets the selectedValue

    @model IList<Example>
    ....
    @for(int i = 0; i < Model.Count; i++)
    {
      @Html.DropDownListFor(m => m[i].FilePath, new SelectList(ViewBag.ConfigFiles, "Value", "Text", Model[i].FilePath), string.Empty, null)
    }
    

    Note that this now generate name attributes which binds to your model

    <select name="[0].FilePath">....<select>
    <select name="[1].FilePath">....<select>
    .... etc
    

    Note that its not necessary to create IEnumerable<SelectListItem> in the controller. Your could instead assign a collection of your objects to ViewBag

    ViewBag.ConfigFiles = db.ConfigFiles;
    

    and in the view

    new SelectList(ViewBag.ConfigFiles, "ID", "Name") // adjust 2nd and 3rd parameters to suit your property names