MVC - Changing default text in dropdown

224 views Asked by At

I have a view model that contains an enum:

public class PasswordChangerIndexViewModel
{
    public enum DatabaseTypes
    {
        Main = 10,
        Florida = 20,
        Illinois = 30,
        Missouri = 40,
        NewHampshire = 50,
        NewJersey = 60,
        Oklahome = 70
    };

    [DisplayName("Database")]
    public DatabaseTypes DatabaseType { get; set; }

}

And in my view, I'm using EnumDropDownListFor to create a drop down list:

<div class="row">
    <div class="col-md-1">
        <div class="form-group">
            @Html.EnumDropDownListFor(z => z.DatabaseType, "** Select a Database **");
        </div>
    </div>
</div>

It's working, but I'm wondering if there is a way to change the text. I want New Hampshire to be rendered instead of NewHampshire and New Jersey instead of NewJersey. Is there a kind of DisplayName attribute or something I can apply to my view model to fix this?

2

There are 2 answers

1
Julien Poulin On BEST ANSWER

Use the DisplayAttribute on your enum members:

public enum DatabaseTypes
{
  Main = 10,
  Florida = 20,
  Illinois = 30,
  Missouri = 40,
  [Display(Name = "New Hampshire")]
  NewHampshire = 50,
  [Display(Name = "New Jersey")]
  NewJersey = 60,
  Oklahome = 70
};

In general, your should favor using [Display] instead of [DisplayName] since it supports localization.

7
DLeh On

You could make your own template for an Enum DropdownList. Here's the one I use that uses an extension method to get the value from an attribute instead of just the name of the enum:

Put this in the Views/Shared/EditorTemplates directory as EnumDropdown.cshtml

@model Enum

@{
    var sort = (bool?)ViewData["sort"] ?? false;
    var enumValues = new List<object>();
    foreach (var val in Enum.GetValues(Model.GetType()))
    {
        enumValues.Add(val);
    }
}

@Html.DropDownListFor(m => m,
    enumValues
    .Select(m =>
    {
        string enumVal = Enum.GetName(Model.GetType(), m);
        var display = m.GetDescription() ?? enumVal;
        return new SelectListItem()
        {
            Selected = (Model.ToString() == enumVal),
            Text = display,
            Value = enumVal
        };
    })
    .OrderBy(x => sort ? x.Text : null)
    ,new { @class = "form-control" })

Here's the code for GetDescription():

    public static string GetDescription(this object enumerationValue)
    {
        Type type = enumerationValue.GetType();
        if (!type.IsEnum)
            throw new ArgumentException("EnumerationValue must be of Enum type", "enumerationValue");

        //Tries to find a DescriptionAttribute for a potential friendly name
        //for the enum
        MemberInfo[] memberInfo = type.GetMember(enumerationValue.ToString());
        if (memberInfo != null && memberInfo.Length > 0)
        {
            object[] attrs = memberInfo[0].GetCustomAttributes(typeof(DescriptionAttribute), false);

            if (attrs != null && attrs.Length > 0)
            {
                //Pull out the description value
                return ((DescriptionAttribute)attrs[0]).Description;
            }
        }
        //If we have no description attribute, just return the ToString of the enum
        return enumerationValue.ToString();

    }

Example Usage below. Model:

public enum MyEnum 
{
    [Description("The First Option1")]
    Option1,
    Option2
}
public class MyModel
{
    [UIHint("EnumDropdown")] //matches EnumDropdown.cshtml
    public MyEnum TheEnum { get; set; }
}

View

@model MyModel
@Html.EditorFor(x => x.TheEnum)

Will create a dropdown with options "The First Option" and "Option2"