Search code examples
c#htmlasp.net-corerazorasp.net-core-mvc

Add default first option as select element when populating select options from an enum field in ASP.NET Core


enum field is defined as:

public enum HasSomething
{
    Installed_by_Installer,
    Not_Installed_by_Installer,
    Not_Present
}

I'm trying to add this to options in a select element as following:

<select asp-for="HasSomething" asp-items="Html.GetEnumSelectList<HasSomething>()" class="form-control">
    <option selected hidden>---Select---</option>
</select> 

The first option ---Select--- is missing out. So first value Installed by Installer automatically becomes the selected value on post which is obviously a wrong input. Can someone please guide how to overcome this problem?

Thanks in advance.


Solution

  • To make this work it's necessary to define your model property to be nullable and set it to null.

    Let say the view model is declared like:

    public class MyModel
    {     
        public HasSomething? Something { get; set; } 
    }
    

    Then in the view use:

    @model MyModel
    
    <select class="form-control"
            asp-for="Something"
            asp-items="@Html.GetEnumSelectList<HasSomething>()">
        <option selected>---Select---</option>
    </select>
    

    Perhaps you need to add the <Nullable> directive to the project file:

    <PropertyGroup>
     <Nullable>enable</Nullable>
      ...   
    </PropertyGroup>
    

    Another solution is to use the Display attribute and add an additional option to the enum values. Then not necessary to define the <option selected>---Select---</option>. The Unassigned value might be set by default.

    public enum HasSomething
    {
        [Display(Name = "---Select---")]
        Unassigned,
        [Display(Name = "Installed by Installer")]
        Installed_by_Installer,
        [Display(Name = "Not Installed by Installer")]
        Not_Installed_by_Installer,
        [Display(Name = "Not Present")]
        Not_Present
    }
    
    public class MyModel
    {     
        public HasSomething? Something { get; set; } = HasSomething.Unassigned;
    }