Enum to Drop Down List Html Helper Extension for ASP MVC 3

Monday, December 24, 2012


In this post I'll go over how to build a MVC3 HtmlHelper extension to map Enum model properties to a dropdown listbox.

The extension will follow the same pattern as out-of-box generic helper functions like @Html.LabelFor<> and @Html.TextBoxFor<>.

Say we have a simple Employee model with Name (string) and Department (nullable enum) fields, and need to make a form for creating new employees:

public enum Department

public class Employee
public string Name { get; set; }
public Department? Dept { get; set; }

We can create a label and textbox for the Name with this View cshtml:

@model Employee

<h2>New Employee</h2>

@Html.LabelFor(model => model.Name)
<br />
@Html.TextBoxFor(model => model.Name)

Which renders into:

There is, however, no way to handle the Department field.  Our goal is to build a custom HtmlHelper to map enum fields like Department to a drop down list.  If the field is Nullable, the dropdown needs to include an empty option.  The end product will work like this:

@Html.LabelFor(model => model.Dept)
<br />
@Html.DropDownEnumListFor(model => model.Dept, Department.Sales)

and render into:

Create Extension Method

Luckily, we don't have to start from scratch.  MVC3 already has a DropDownListFor<> helper, which takes as input a SelectList object containing objects to populate the dropdown.

The bulk of our work will be in building an appropriate SelectList from a given enum.

First, let's create the DropDownEnumListFor<> extension method.  Add a static class to your MVC project.  It doesn't matter where you put it or what it's called.  Remember to import System.Web.Mvc, System.Web.Mvc.Html, and System.Linq.Expressions namespaces.

public static class Extensions
public static MvcHtmlString DropDownEnumListFor<TModel, TValue>(
this HtmlHelper<TModel> helper,
Expression<Func<TModel, TValue>> expr,
TValue selectedItem)
return helper.DropDownListFor(expr, ToSelectList<TValue>(selectedItem));

public static SelectList ToSelectList<T>(T selectedValue)
throw new NotImplementedException();

The expr parameter is a lamba function that takes as input the model and returns your property value.  On the View page, this is the model => model.Dept part.  selectedItem is the enum value that should be selected initially.

At this point, the new method should be available in Intellisense.  Remember to add a using statement in the View cshtml for the namespace your extension lives under.

Now we have to implement ToSelectList<T>, which converts any given Enum type T to a SelectList.

Handle Nullable Enums

Let's start by creating two helper methods to deal with Nullable enum types.

public static bool IsTypeNullable(Type type)
return (type.IsGenericType
&& type.GetGenericTypeDefinition() == typeof(Nullable<>));

public static Type GetBaseType(Type type)
return IsTypeNullable(type) ? type.GetGenericArguments()[0] : type;

IsTypeNullable simply checks if the specified type is Nullable.  GetBaseType converts a Nullable type to it's non-nullable type (ie decimal? to decimal).

Implement ToSelectList

Finally, implement ToSelectList<T>:

  1. If T is Nullable, retrieve the Enum type with GetBaseType
  2. If T is Nullable, add an empty option
  3. Get list of enum values using Enum.GetValues
  4. Build an ArrayList pairing each enum value with its display name
  5. Create a SelectList from the ArrayList


public static SelectList ToSelectList<T>(T selectedValue)
bool isNullable = IsTypeNullable( typeof(T) );
Type enumType = GetBaseType( typeof(T) );

if (enumType.IsEnum)
ArrayList items = new ArrayList();

// Add empty option
if (isNullable)
items.Add( new { Name = "", Value = default(T) } );

// Add enum values
var enumValues= Enum.GetValues(enumType);

foreach (T value in enumValues)
string displayName = Enum.GetName(enumType, value);
items.Add( new { Name = displayName, Value = value } );

return new SelectList(items, "Value", "Name", selectedValue);

return null;



Post a Comment