LastBye
LastBye

Reputation: 1173

How do I perform an Enum binding to a view's model in .NET's MVC?

How can I bind an enum into a drop down in MVC to make the model be valid after a post? Not sure does it need a converter or something else, I provide the code, what is your recommended solution? (the below code causes ModelError)

Enum :

public enum TimePlan
{   Routine = 0,
    Single = 1 }

The Model :

 public TimePlan TheTimePlan { get; set; }

 public SelectListItem[] TimeList { get; set; }

Controller :

    [HttpPost]
    public virtual ActionResult Education(EducationViewModel EducationModelInfo)
    {
        if (ModelState.IsValid)
        { ...
    } }

The View Binding :

@Html.DropDownListFor(m => m.CourseTimePlan, Model.TimeList, "Please select the time plan") 

Upvotes: 0

Views: 5943

Answers (1)

Darin Dimitrov
Darin Dimitrov

Reputation: 1038790

You haven't shown how you populated this TimeList collection. Try like this and it should work:

public TimePlan TheTimePlan { get; set; }

public IEnumerable<SelectListItem> TimeList
{
    get
    {
        var enumType = typeof(TimePlan);
        var values = Enum.GetValues(enumType).Cast<TimePlan>();

        var converter = TypeDescriptor.GetConverter(enumType);

        return
            from value in values
            select new SelectListItem
            {
                Text = converter.ConvertToString(value),
                Value = value.ToString(),
            };
    }
}

or to make it a little more generic you could write a reusable helper:

public static IHtmlString DropDownListForEnum<TModel, TEnum>(
    this HtmlHelper<TModel> htmlHelper, 
    Expression<Func<TModel, TEnum>> expression
)
{
    var metadata = ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData);
    var enumType = GetNonNullableModelType(metadata);
    var values = Enum.GetValues(enumType).Cast<TEnum>();
    var converter = TypeDescriptor.GetConverter(enumType);

    var items =
        from value in values
        select new SelectListItem
        {
            Text = converter.ConvertToString(value), 
            Value = value.ToString(), 
            Selected = value.Equals(metadata.Model)
        };

    return htmlHelper.DropDownListFor(expression, items);
}

and then your model could only contain the Enum value:

public TimePlan TheTimePlan { get; set; }

and in your view use the helper:

@Html.DropDownListForEnum(x => x.TheTimePlan)

Upvotes: 9

Related Questions