Introduction
Sometimes, we have a scenario during development where we need to populate DropDownList from Enum. There are a couple of ways to do it. But every way has its pros and cons. One should always keep in mind the SOLID and DRY principle while writing code. I will show two ways to do it and you will be able to understand which one is better and why it is better.
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 the 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
- }
- var enumData = from eUserRole e in Enum.GetValues(typeof(eUserRole))
- select new
- {
- ID = (int)e,
- Name = e.ToString()
- };
- ViewBag.EnumList = new SelectList(enumData,"ID","Name");
- @Html.DropDownList("EnumDropDown",ViewBag.EnumList as SelectList)
The problem with the above method is that whenever we have Enum to be bind 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 of a 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");
- }
- }
- ViewBag.EnumList = eUserRole.SuperAdmin.ToSelectList();
- @Html.DropDownList("EnumDropDown",eUserRole.SuperAdmin.ToSelectList())
We can extend the extension method according to our requirements.
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);
- }
- }
- @Html.DropDownList("EnumDropDownWithSelected",
- eUserRole.SuperAdmin.ToSelectList((int)eUserRole.OfficeAdmin))
In most cases, we don't want to show Enum value in 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 in the 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;
- }
- }
- }
- 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
- }
- 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;
- }
- }
- public static string AttributeValue<TEnum,TAttribute>(this TEnum value,Func<TAttribute,string> func)
- where T : Attribute
- {
- FieldInfo field = value.GetType().GetField(value.ToString());
- T attribute = Attribute.GetCustomAttribute(field, typeof(T)) as T;
- return attribute == null ? value.ToString() : func(attribute);
- }
- public static System.Web.Mvc.SelectList ToSelectList<TEnum,TAttribute>
- (this TEnum obj,Func<TAttribute,string> func,object selectedValue=null)
- where TEnum : struct, IComparable, IFormattable, IConvertible
- where TAttribute : Attribute
- {
- return new SelectList(Enum.GetValues(typeof(TEnum)).OfType<Enum>()
- .Select(x =>
- new SelectListItem
- {
- Text = x.AttributeValue<TEnum,TAttribute>(func),
- Value = (Convert.ToInt32(x)).ToString()
- }),
- "Value",
- "Text",
- selectedValue);
- }
- @Html.DropDownList("EnumDropDownWithSelected", eUserRole.SuperAdmin.ToSelectList<eUserRole,
- numDisplayNameAttribute>(attr=>attr.DisplayName,(int)eUserRole.OfficeAdmin))

Ehsan SajjadPosted Aug 3, 2016, 10:15 AM
Thanks for the read Asad Ali Raja Munesh Sharma Sirisha K Prasanna M kalu singh rao
RajaPosted Jul 4, 2016, 12:36 AM
Nice Share...
Asad AliPosted Jul 3, 2016, 3:13 PM
Good one
Munesh SharmaPosted Jul 3, 2016, 1:02 PM
Nice
Sirisha KPosted Jul 3, 2016, 12:52 PM
Good one
Prasanna MuraliPosted Jul 3, 2016, 11:09 AM
Nice one...
kalu singh raoPosted Jul 3, 2016, 7:10 AM
Nice...
Ehsan SajjadPosted Jan 14, 2016, 7:34 AM
Thanks to all
Santhakumar MunuswamyPosted Dec 23, 2015, 3:46 PM
Thanks for nice article
Ali AhmedPosted Dec 20, 2015, 2:25 PM
nice..
Humayun Kabir MamunPosted Dec 20, 2015, 1:35 AM
Nice...
Raja TPosted Dec 19, 2015, 7:31 AM
Nice, Thanks for sharing