Greg Burghardt
Greg Burghardt

Reputation: 18783

DropDownListFor HTML helper not selecting option for Enum model property

I have an ASP.NET MVC 4 site and a domain model that uses an Enum. I'm able to generate a list of SelectListItem objects, but the proper item is not selected.

Domain Model

public enum ApplicationStatus
{
    Unknown = 0,
    Incomplete = 1,
    Submitted = 2,
    Error = 4
}

public class Application
{
    public ApplicationStatus Status { get; set; }

    // ...
}

The "Edit" View

@model Application

@using (Html.BeginForm("Edit", "Applications", new { ... }, FormMethod.Post, new { role = "form", @class = "form-horizontal" }))
{
    @Html.Partial("_Form", Model)

    <p>
        @Html.ActionLink("Cancel", "Details", new { ... }, new { @class = "btn btn-default" })
        <button type="submit" class="btn btn-primary">Save</button>
    </p>
}

The "_Form" Partial

@model BWE.Models.Entity.BitWeb.Application

@Html.ValidationSummary(true)

<div class="form-group">
    @Html.LabelFor(model => model.Status, new { @class = "col-sm-2" })
    <div class="col-sm-10">
        @Html.DropDownListFor(model => model.Status, SelectHelper.GetApplicationStatusOptions(Model.Status))
        @Html.ValidationMessageFor(model => model.Status)
    </div>
</div>

SelectHelper

public static class SelectHelper
{
    public static IEnumerable<SelectListItem> GetApplicationStatusOptions(ApplicationStatus currentStatus)
    {
        var items = new List<SelectListItem>()
        {
            new SelectListItem()
            {
                Text = "Select",
                Value = string.Empty
            }
        };

        IEnumerable<ApplicationStatus> statuses = Enum.GetValues(typeof(ApplicationStatus)).Cast<ApplicationStatus>();

        foreach (var status in statuses)
        {
            if (status == ApplicationStatus.Unknown)
                continue;

            items.Add(new SelectListItem()
            {
                Text = status.ToString(),
                Value = ((int)status).ToString(),
                Selected = status == currentStatus
            });
        }

        return items;
    }
}

The "Select" option is always selected in the dropdown even though I can step through the code and see one of the SelectListItem objects get their Selected property set to true.

I've tried the solution recommended in My templated helper using a DropDownListFor does NOT reflect the model of enum. Why?, but this solution was geared towards MVC 3. I tried the solution (passing a SelectList object as the second argument to Html.DropDownListFor) and all I got was a dropdown list with 4 options whose display text was "System.Web.Mvc.SelectListItem" and no values for the <option> tags.

Furthermore, I tried other solutions that created an @Html.EnumDropDownListFor(...) helper function, which behaved the same way. It seems that all though the proper SelectListItem is getting selected, maybe the current Model.Status value is overriding it?

Update #1

I added an integer property called StatusId which gets and sets the Status property as an integer, and this works when calling Html.DropDownListFor(model => model.StatusId, ...) however I was hoping for a solution that allows me to use the enum value directly, not as a proxy through another property.

Upvotes: 1

Views: 1397

Answers (1)

Chris Pratt
Chris Pratt

Reputation: 239270

For some crazy reason, enum values are rendered as their string-based names by Razor, rather than their integer value counterparts. Regardless, my guess is that your SelectHelper is returning options with values as integers, which is why converting your enum value to an int allowed the selection to work. Since this is a custom component you have anyways, I would suggest simply modifying your helper to return the enum string names as the option values instead of ints. Then the property value and the option values will line up properly.

Upvotes: 2

Related Questions