Bind Enum to DropdownList in asp.net mvc
Introduction:
Approach 1 (Typical Way):
The first approach in my point of view is not very elegant but it will surely do what we want it to.Consider following Enum which we want to populate in the drop down:
public enum eUserRole : int { SuperAdmin = 0, PhoenixAdmin = 1, OfficeAdmin = 2, ReportUser = 3, BillingUser = 4 }
So normally what we do is create SelectList by adding each Enum value following way in the action:
var enumData = from eUserRole e in Enum.GetValues(typeof(eUserRole)) select new { ID = (int)e, Name = e.ToString() };
Now set it in ViewBag so that we can use it in View:
ViewBag.EnumList = new SelectList(enumData,"ID","Name");
and Now in View:
@Html.DropDownList("EnumDropDown",ViewBag.EnumList as SelectList)
Problem in Approach 1:
The problem with the above way is that whenever we have Enum to be binded with some Html Helper we have to write the above linq query code to get the enum all values in the action which is a bit pain to rewrite one thing again and again.We will see next how we can make it better and reusable.Approach 2:
Now here is an elegant way to achieve it using Extension Method and Generics, which will return us Enum values as a SelectList for any type of Enum:public static class ExtensionMethods { public static System.Web.Mvc.SelectList ToSelectList<TEnum>(this TEnum obj) where TEnum : struct, IComparable, IFormattable, IConvertible { return new SelectList(Enum.GetValues(typeof(TEnum)).OfType<Enum>() .Select(x => new SelectListItem { Text = Enum.GetName(typeof(TEnum), x), Value = (Convert.ToInt32(x)).ToString() }), "Value", "Text"); } }
and now we just need to call it on any Enum in action this way:
ViewBag.EnumList = eUserRole.SuperAdmin.ToSelectList();
we can also use it directly in the View, just we have to include namespace in case it's in seperate namespace:
@Html.DropDownList("EnumDropDown",eUserRole.SuperAdmin.ToSelectList())
You will probably need to set selected value of dropdownlist in the case when user is editing record.
We can extend the extension method according to our requirents.
Overload with Selected Value parameter:
Here is the extension method overload to pass selected value in case we want to set selected value, you can write other overloads as well according to the need:public static class ExtensionMethods { public static System.Web.Mvc.SelectList ToSelectList<TEnum>(this TEnum obj,object selectedValue) where TEnum : struct, IComparable, IFormattable, IConvertible { return new SelectList(Enum.GetValues(typeof(TEnum)).OfType<Enum>() .Select(x => new SelectListItem { Text = Enum.GetName(typeof(TEnum), x), Value = (Convert.ToInt32(x)).ToString() }), "Value", "Text",selectedValue); } }
and usage in View this way:
@Html.DropDownList("EnumDropDownWithSelected",eUserRole.SuperAdmin.ToSelectList((int)eUserRole.OfficeAdmin))
Now the drop down will have OfficeAdmin selected by default.
In most of cases we don't want to show Enum value I'm dropdown list instead of that we want to show user friendly term as dropdown text, for that purpose we can write our Attribute for Enum following way:
Create a custom class which inherits from Attribute type:
public class EnumDisplayNameAttribute : Attribute { private string _displayName; public string DisplayName { get { return _displayName; } set { _displayName = value; } } }
and Now use attribute on Enum :
public enum eUserRole : int { [EnumDisplayName(DisplayName="Super Admin")] SuperAdmin = 0, [EnumDisplayName(DisplayName = "Phoenix Admin")] PhoenixAdmin = 1, [EnumDisplayName(DisplayName = "Office Admin")] OfficeAdmin = 2, [EnumDisplayName(DisplayName = "Report User")] ReportUser = 3, [EnumDisplayName(DisplayName = "Billing User")] BillingUser = 4 }
Now we will need to modify or write another extension method as now we need to pick value of DisplayName attribute.
We now have to extension methods now, one which return specific Enum value DisplayName Attribute value and second which return SelectList against for Enum:
public static class ExtensionMethods { public static System.Web.Mvc.SelectList ToSelectList<TEnum>(this TEnum obj) where TEnum : struct, IComparable, IFormattable, IConvertible // correct one { return new SelectList(Enum.GetValues(typeof(TEnum)).OfType<Enum>() .Select(x => new SelectListItem { Text = x.DisplayName(), Value = (Convert.ToInt32(x)).ToString() }), "Value", "Text"); } public static string DisplayName(this Enum value) { FieldInfo field = value.GetType().GetField(value.ToString()); EnumDisplayNameAttribute attribute = Attribute.GetCustomAttribute(field, typeof(EnumDisplayNameAttribute)) as EnumDisplayNameAttribute; return attribute == null ? value.ToString() : attribute.DisplayName; } }
2 comments
Write commentsIn ASP.NET MVC 5.1 it's fairly simple, you only need to write just a single line of code.
ReplyMVC 5.1 provides new HTML helper for Enum support as drop-down i.e. EnumDropDownListFor helper method. Use this as following
@Html.EnumDropDownListFor(model=>model.EnumtypeProperty)
Below article provide in detail implementation for same
http://modernpathshala.com/Article/1030/enum-support-in-mvc5-1
yes before asp.net mvc 5 we have to write our custom html helper.
Reply