Bind Enum with dropdown and set selected value on get action in MVC C#

16,009

Solution 1

I blogged about this very subject whereby I create an EnumHelper to help with this common task.

http://jnye.co/Posts/4/creating-a-dropdown-list-from-an-enum-in-mvc-and-c%23

In your controller:

//If you don't have an enum value use the type
ViewBag.DropDownList = EnumHelper.SelectListFor<MyEnum>();

//If you do have an enum value use the value (the value will be marked as selected)    
ViewBag.DropDownList = EnumHelper.SelectListFor(MyEnum.MyEnumValue);

In your View:

@Html.DropDownList("DropDownList")
@* OR *@
@Html.DropDownListFor(m => m.Property, ViewBag.DropDownList as SelectList, null)

The helper class:

public static class EnumHelper
{
    // Get the value of the description attribute if the   
    // enum has one, otherwise use the value.  
    public static string GetDescription<TEnum>(this TEnum value)
    {
        var fi = value.GetType().GetField(value.ToString());

        if (fi != null)
        {
            var attributes = (DescriptionAttribute[])fi.GetCustomAttributes(typeof(DescriptionAttribute), false);

            if (attributes.Length > 0)
            {
                return attributes[0].Description;
            }
        }

        return value.ToString();
    }

    /// <summary>
    /// Build a select list for an enum
    /// </summary>
    public static SelectList SelectListFor<T>() where T : struct
    {
        Type t = typeof(T);
        return !t.IsEnum ? null
                         : new SelectList(BuildSelectListItems(t), "Value", "Text");
    }

    /// <summary>
    /// Build a select list for an enum with a particular value selected 
    /// </summary>
    public static SelectList SelectListFor<T>(T selected) where T : struct
    {
        Type t = typeof(T);
        return !t.IsEnum ? null
                         : new SelectList(BuildSelectListItems(t), "Text", "Value", selected.ToString());
    }

    private static IEnumerable<SelectListItem> BuildSelectListItems(Type t)
    {
        return Enum.GetValues(t)
                   .Cast<Enum>()
                   .Select(e => new SelectListItem { Value = e.ToString(), Text = e.GetDescription() });
    }
}

Solution 2

This is the code I use for enums in dropdowns. Then just use @Html.DropDown/For(); and put this SelectList in as param.

public static SelectList ToSelectList(this Type enumType, string selectedValue)
    {
        var items = new List<SelectListItem>();
        var selectedValueId = 0;
        foreach (var item in Enum.GetValues(enumType))
        {
            FieldInfo fi = enumType.GetField(item.ToString());
            DescriptionAttribute[] attributes = (DescriptionAttribute[])fi.GetCustomAttributes(typeof(DescriptionAttribute), false);
            var title = "";
            if (attributes != null && attributes.Length > 0)
            {
                title = attributes[0].Description;
            }
            else
            {
                title = item.ToString();
            }

            var listItem = new SelectListItem
            {
                Value = ((int)item).ToString(),
                Text = title,
                Selected = selectedValue == ((int)item).ToString(),
            };
            items.Add(listItem);
        }

        return new SelectList(items, "Value", "Text", selectedValueId);
    }

Also you can extend DropDownFor like this:

public static MvcHtmlString EnumDropdownListFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, Type enumType, object htmlAttributes = null)
    {
        ModelMetadata metadata = ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData);

        SelectList selectList = enumType.ToSelectList(metadata.Model.ToString());

        return htmlHelper.DropDownListFor(expression, selectList, htmlAttributes);
    }

Usage then looks like this:

@Html.EnumDropdownListFor(model => model.Property, typeof(SpecificEnum))
Share:
16,009
Satish Singh
Author by

Satish Singh

Software engineer with 10+ years’ experience developing robust code for high-volume businesses. Helped clients and product owners by capturing, analyzing and documenting their requirements and then providing the best implementation and designs. The objective is to adapt this constantly changing software field to get best out of it, for my organization and for my clients.

Updated on June 11, 2022

Comments

  • Satish Singh
    Satish Singh almost 2 years

    I have a Enum called CityType

    public enum CityType
        {
            [Description("Select City")]
            Select = 0,
    
            [Description("A")]
            NewDelhi = 1,
    
            [Description("B")]
            Mumbai = 2,
    
            [Description("C")]
            Bangalore = 3,
    
            [Description("D")]
            Buxar = 4,
    
            [Description("E")]
            Jabalpur = 5
        }
    

    Generate List from Enum

    IList<SelectListItem> list = Enum.GetValues(typeof(CityType)).Cast<CityType>().Select(x =>    new SelectListItem(){ 
        Text = EnumHelper.GetDescription(x), 
        Value = ((int)x).ToString()
    }).ToList(); 
    
    int city=0; 
    if (userModel.HomeCity != null) city= (int)userModel.HomeCity;
    ViewData["HomeCity"] = new SelectList(list, "Value", "Text", city);
    

    Bind on .cshtml

    @Html.DropDownList("HomeCity",null,new { @style = "width:155px;", @class = "form-control" })
    

    EnumHelper GetDescription Class to get Description of Enum

  • Seth
    Seth over 9 years
    What is the EnumExtension.ToSelectList? That a custom class?
  • TheCodeDestroyer
    TheCodeDestroyer over 9 years
    Its just a class where this ToSelectList() method lives. Altho it would be cleaner to use the enumType param as this, so you would then use it like: enumType.ToSelectList(metadata.Model.ToString()) I can change the answer to show this usage if you want.
  • Seth
    Seth over 9 years
    Yes can you please update cause i can't seem to get it. Do i need to create a ToSelectList, cause its not avialble? Thanks!
  • TheCodeDestroyer
    TheCodeDestroyer over 9 years
    Ok updated ToSelectList list and EnumDropdownListFor methods.
  • isaolmez
    isaolmez over 8 years
    Thanks for the example. I have changed enumType.ToSelectList(metadata.Model.ToString()) to metadata.ModelType.ToSelectList(metadata.Model.ToString()). But I had to change method name to avoid ambigous method call.