Search code examples
c#asp.net-mvcrazorselectlistitem

Selected property on SelectListItem not being set by SelectList constructor


I'm creating a SelectList to pass to a Html.DropDownList, but the correct value doesn't seem to be populating

var x = new SelectList(new[] { 
    new SelectListItem() { Value="1", Text="Vanilla"}, 
    new SelectListItem() { Value="2", Text="Chocolate"},
    new SelectListItem() { Value="3", Text="Strawberry"}
}, "Value", "Text", "2");

SelectList should take a constructor that takes in the selectedValue:

public SelectList(
    IEnumerable items,
    string dataValueField,
    string dataTextField,
    object selectedValue
)

But this only sets the SelectedValue on the entire collection. The individual SelectListItems haven't been set as Selected

Inspector

Do I need to iterate over them individually and set selected for each as in this question?


Solution

  • The Selected property is being set by the SelectList constructor. The image you have shown is for the items argument (i.e the collection of SelectListItem that you passing to the method), not the result of calling the method.

    The constructor does not modify the collection passed to it, it creates a new IEnumerable<SelectListItem>, and if you inspect the value of var x, then you will see that the 2nd SelectListItem (the one with Value = "2") will have its Selected property set to true.

    However, the purpose of the SelectListItem class is for use in one of the HtmlHelper methods that generates a <select> (DropDownList(), DropDownListFor(), ListBox() and ListBoxFor() methods) which accept an IEnumerable<SelectListItem> as either the 1st or 2nd argument.

    Unless you specifically not binding to a model property (e.g. @Html.DropDownList("NotAModelProperty", Model.YourSelectList)), then setting the Selected property is ignored because the method sets the selected option based on the value of the property your binding to (refer How to set “selectedValue” in DropDownListFor Html helper for more detail), therefore creating a new IEnumerable<SelectListItem> from the first one by using new SelectList(...) is pointless extra overhead.

    The reason for using the SelectList constructor is to create an IEnumerable<SelectListItem> from an existing collection of objects, for example

    IEnumerable<SelectListItem> options = new SelectList(db.Flavors, "ID", "Name")
    

    which would get the records from the Flavors table, and set the Value based on its ID property, and the Text based on its Name property. It just provides an alternative to using (say)

    IEnumerable<SelectListItem> options = db.Flavors.Select(x => new SelectListItem
    {
        Value = x.ID.ToString(),
        Text = x.Name
    });