ASP.NET MVC Dropdown List From SelectList

asp.net-mvc, c#, drop-down-menu

Solution

You are missing setting the Text and Value field in the SelectList itself. That is why it does a `.ToString()` on each object in the list. You could think that given it is a list of `SelectListItem` it should be smart enough to detect this... but it is not.

u.UserTypeOptions = new SelectList(
    new List<SelectListItem>
    {
        new SelectListItem { Selected = true, Text = string.Empty, Value = "-1"},
        new SelectListItem { Selected = false, Text = "Homeowner", Value = ((int)UserType.Homeowner).ToString()},
        new SelectListItem { Selected = false, Text = "Contractor", Value = ((int)UserType.Contractor).ToString()},
    }, "Value" , "Text", 1);

BTW, you can use a list or array of any type... and then just set the name of the properties that will act as Text and Value.

I think it is better to do it like this:

u.UserTypeOptions = new SelectList(
    new List<SelectListItem>
    {
        new SelectListItem { Text = "Homeowner", Value = ((int)UserType.Homeowner).ToString()},
        new SelectListItem { Text = "Contractor", Value = ((int)UserType.Contractor).ToString()},
    }, "Value" , "Text");

I removed the -1 item, and the setting of each item selected true/false.

Then, in your view:

@Html.DropDownListFor(m => m.UserType, Model.UserTypeOptions, "Select one")

This way, if you set the "Select one" item and don't set one item as selected in the SelectList, the `UserType` will be null (the `UserType` need to be `int?` ).

If you need to set one of the SelectList items as selected, you can use:

u.UserTypeOptions = new SelectList(options, "Value" , "Text", userIdToBeSelected);

As one of the users explained in the comments: The 4th option of the SelectList constructor is ignored when binding to a property using `DropDownListFor()` - it is the property's value that determines what is selected.

Problem

I am building the following `SelectList` in my controller. ``` var u = new NewUser(); u.UserTypeOptions = new SelectList(new List<SelectListItem> { new SelectListItem { Selected = true, Text = string.Empty, Value = "-1"}, new SelectListItem { Selected = false, Text = "Homeowner", Value = ((int)UserType.Homeowner).ToString()}, new SelectListItem { Selected = false, Text = "Contractor", Value = ((int)UserType.Contractor).ToString()}, }); return u; ``` And displaying it on my view like this: ``` @Html.DropDownListFor(m => m.UserType, Model.UserTypeOptions) ``` It looks like I am giving it a valid set of `SelectListItem`s in what should be a pretty straightforward dropdown list, but instead of getting a valid `<option>` list with good values and text, I get this: ``` <select data-val="true" data-val-range="A user type must be selected." data-val-range-max="2" data-val-range-min="1" data-val-required="The UserType field is required." id="UserType" name="UserType" class="input-validation-error"> <option>System.Web.Mvc.SelectListItem</option> <option>System.Web.Mvc.SelectListItem</option> <option>System.Web.Mvc.SelectListItem</option> </select> ``` What gives? As far as I can tell, this should work.

Original source