My model is:
public class DynamicEnum
{
public string Name {get; set;}
public int Value {get; set;}
}
public class ViewModel
{
public DynamicEnum DynamicEnum {get; set;}
}
Public ActionResult MyAction
{
var model = new ViewModel();
model.DynamicEnum = new DynamicEnum(){ Name = "System.DayOfWeek", Value = 2};
return View(model);
}
So in the view I need a HtmlHelper to dynamically generate DropDownListFor like:
@Html.EnumDropDownListFor(m => m.DynamicEnum)
I used MVC 5.2.3, Does any one have any idea?
One way to achieve this would be to use reflection:
public static class HtmlExtensions
{
public static IHtmlString EnumDropDownListFor<TModel>(
this HtmlHelper<TModel> html,
Expression<Func<TModel, DynamicEnum>> expression)
{
var metadata = ModelMetadata.FromLambdaExpression(expression, html.ViewData);
var dynamicEnum = (DynamicEnum)metadata.Model;
var enumType = Type.GetType(dynamicEnum.Name, true);
if (!enumType.IsEnum)
{
throw new Exception(dynamicEnum.Name + " doesn't represent a valid enum type");
}
// TODO: You definetely want to cache the values here to avoid the expensive
// reflection call: a ConcurrentDictionary<Type, IList<SelectListItem>> could be used
var enumNames = Enum.GetNames(enumType);
var values = enumNames.Select(x => new SelectListItem
{
Text = x,
Value = ((int)Enum.Parse(enumType, x)).ToString(),
}).ToList();
string name = ExpressionHelper.GetExpressionText(expression) + ".Value";
return html.DropDownList(name, values);
}
}
Remark: The HtmlHelper.EnumDropDownListFor
extension method already exists in ASP.NET MVC so make sure that you bring the namespace in which you declared your custom extension method into scope to avoid collisions. Or just use a different method name.