Search code examples
asp.net-coreasp.net-core-mvc.net-corehtml.dropdownlistforeditorformodel

Enum DropDownList always returns the first value in the list


I've created several EditorTemplates for some Enums I'm using so that they will display as DropDownLists when I use EditorForModel(). However when I submit the form after selecting an item from the list, It always submits the first item in the dropdown instead of the selected one.

For example, if I have an enum called "Sizes" and it has the values 'Small', 'Medium', and 'Large'. EditorForModel will create a dropdown that displays them in the order 'Small', 'Medium', 'Large'. If I then select 'Large' and then look at the details for the model entry that was made into the database, it will say 'Small' which is incorrect.

Here's some example code of what I have:

Sizes.cshtml (Editor Template)

@model Options.Sizes 

@{ 
    var values = Enum.GetValues(typeof(Options.Sizes)).Cast<Options.Sizes>();

    IEnumerable<SelectListItem> items =
        from value in values
        select new SelectListItem
        {
            Text = value.ToString(),
            Value = value.ToString(),
            Selected = (value.Equals(Options.Sizes.Small))
        };
}

@Html.DropDownList("Size", items)

Options.cs (Class that holds the enum)

public class Options
{
    public enum Sizes
    {
        Small,
        Medium,
        Large
    };
}

Create.cshtml (View)

@model = ProjectName.Models.Ball

<form asp-action="Create" asp-controller="Ball">
    @Html.EditorForModel()
    <input type="submit" value="submit">
</form>

Ball.cs (Model)

public class Ball
{
    [Key]
    public Nullable<int> ID { get; set; }

    public string Name { get; set; }

    public Options.Sizes Size { get; set; }
}

Somehow the Size property of Ball is always the first value in the dropdown, which is 'Small'. No matter what I pick.


Solution

  • If you inspect the dropdown in the browser, with your version you'll see it has the name Size.Size. This causes the binding not to work when you post to your Create action (assuming that's just expecting a Ball model, as you haven't included it here), because that is expecting something with the name Size.

    It works for me when I change your EditorTemplate so the final line is:

    @Html.DropDownListFor(m => m, items)
    

    Using DropDownListFor ensures the generated select element gets the right name.