Mvc3 Razor Dropdownlistfor Enums

MVC3 Razor DropDownListFor Enums

I've just made one for my own project. The code below is part of my helper class, I hope that I got all methods needed. Write a comment if it doesn't work, and I'll check again.

public static class SelectExtensions
{

public static string GetInputName<TModel, TProperty>(Expression<Func<TModel, TProperty>> expression)
{
if (expression.Body.NodeType == ExpressionType.Call)
{
MethodCallExpression methodCallExpression = (MethodCallExpression)expression.Body;
string name = GetInputName(methodCallExpression);
return name.Substring(expression.Parameters[0].Name.Length + 1);

}
return expression.Body.ToString().Substring(expression.Parameters[0].Name.Length + 1);
}

private static string GetInputName(MethodCallExpression expression)
{
// p => p.Foo.Bar().Baz.ToString() => p.Foo OR throw...
MethodCallExpression methodCallExpression = expression.Object as MethodCallExpression;
if (methodCallExpression != null)
{
return GetInputName(methodCallExpression);
}
return expression.Object.ToString();
}

public static MvcHtmlString EnumDropDownListFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression) where TModel : class
{
string inputName = GetInputName(expression);
var value = htmlHelper.ViewData.Model == null
? default(TProperty)
: expression.Compile()(htmlHelper.ViewData.Model);

return htmlHelper.DropDownList(inputName, ToSelectList(typeof(TProperty), value.ToString()));
}

public static SelectList ToSelectList(Type enumType, string selectedItem)
{
List<SelectListItem> items = new List<SelectListItem>();
foreach (var item in Enum.GetValues(enumType))
{
FieldInfo fi = enumType.GetField(item.ToString());
var attribute = fi.GetCustomAttributes(typeof(DescriptionAttribute), true).FirstOrDefault();
var title = attribute == null ? item.ToString() : ((DescriptionAttribute)attribute).Description;
var listItem = new SelectListItem
{
Value = ((int)item).ToString(),
Text = title,
Selected = selectedItem == ((int)item).ToString()
};
items.Add(listItem);
}

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

Use it as:

Html.EnumDropDownListFor(m => m.YourEnum);

Update

I've created alternative Html Helpers. All you need to do to use them is to change your baseviewpage in views\web.config.

With them you can just do:

@Html2.DropDownFor(m => m.YourEnum);
@Html2.CheckboxesFor(m => m.YourEnum);
@Html2.RadioButtonsFor(m => m.YourEnum);

More info here: http://blog.gauffin.org/2011/10/first-draft-of-my-alternative-html-helpers/

ASP.NET MVC3 DropDownListFor Enum

Add a SelectList property to your viewmodel and populate as per @Brandon's answer here.

Then you will change your code to:

@Html.DropDownListFor(model => model.Booking.Day, Model.SelectListProperty)

(where SelectListProperty is the name of your property on your viewmodel)

DropDownListFor enum doesn't bind back to the model

Create Dictionary where Key will be integer representation of the enum and string- the name of enum.

@Html.DropDownListFor(model => model.response, 
new SelectList(Enum.GetValues(typeof(Vouchers.Models.ResponseType)).OfType<Vouchers.Models.VoucherResponseType>().ToDictionary(x => Convert.ToInt32(x), y => y.ToString()), "Key", "Value"), "Please Select")

Sorry for possible errors, I have not tried it.

How do you create a dropdownlist from an enum in ASP.NET MVC?

For MVC v5.1 use Html.EnumDropDownListFor

@Html.EnumDropDownListFor(
x => x.YourEnumField,
"Select My Type",
new { @class = "form-control" })

For MVC v5 use EnumHelper

@Html.DropDownList("MyType", 
EnumHelper.GetSelectList(typeof(MyType)) ,
"Select My Type",
new { @class = "form-control" })

For MVC 5 and lower

I rolled Rune's answer into an extension method:

namespace MyApp.Common
{
public static class MyExtensions{
public static SelectList ToSelectList<TEnum>(this TEnum enumObj)
where TEnum : struct, IComparable, IFormattable, IConvertible
{
var values = from TEnum e in Enum.GetValues(typeof(TEnum))
select new { Id = e, Name = e.ToString() };
return new SelectList(values, "Id", "Name", enumObj);
}
}
}

This allows you to write:

ViewData["taskStatus"] = task.Status.ToSelectList();

by using MyApp.Common

DropDownListFor enums in EF5

This is the solution, its just a shame that its not simple to modify the TT templates to automate this.

@Html.DropDownListFor(model => model.TypeID, new SelectList(Enum.GetValues(typeof(Models.OrganisationType))))

This displays a dropdowncombo with the Textual values in it i.e. company, department, location.

MVC3 EnumDropdownList selected value

I had the same issue with enums which actually had custom value set

public enum Occupation
{
[Description("Lorry driver")] LorryDriver = 10,
[Description("The big boss")] Director = 11,
[Description("Assistant manager")] AssistantManager = 12
}

What I found is that when I use DropDownListFor(), it doesn't use the selected item from the SelectListItem collection to set the selected option. Instead it selects an option with a value which equals to the property I'm trying to bind to (m => m.Occupation) and for this it uses the enum's .ToString() not the enum's actual integer value. So what I ended up with is setting the SelectListItem's Value like so:

var listItem = new SelectListItem
{
Value = item.ToString(), // use item.ToString() instead
Text = title,
Selected = selectedItem == item.ToString() // <- no need for this
};

The helper method:

public static class SelectListItemsForHelper
{
public static IEnumerable<SelectListItem> SelectListItemsFor<T>(T selected) where T : struct
{
Type t = typeof(T);
if (t.IsEnum)
{
return Enum.GetValues(t).Cast<Enum>().Select(e => new SelectListItem { Value = e.ToString(), Text = e.GetDescription() });
}
return null;
}

public static string GetDescription<TEnum>(this TEnum value)
{
FieldInfo 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();
}
}

In the view:

@Html.DropDownListFor(m => m.Occupation, SelectListItemsForHelper.SelectListItemsFor(Model.Occupation), String.Empty)


Related Topics



Leave a reply



Submit