Bind Enum with dropdown and set selected value on get action in MVC C#
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))
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, 2022Comments
-
Satish Singh almost 2 years
I have a
Enum
calledCityType
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 over 9 yearsWhat is the EnumExtension.ToSelectList? That a custom class?
-
TheCodeDestroyer over 9 yearsIts 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 over 9 yearsYes 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 over 9 yearsOk updated ToSelectList list and EnumDropdownListFor methods.
-
isaolmez over 8 yearsThanks 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.