DropDownListFor - does not select "Selected" value

Dmitry Efimenko picture Dmitry Efimenko · Mar 23, 2012 · Viewed 21.6k times · Source

Another one of these questions regarding DropDownListFor not selecting the "Selected" value. Here is code:

Model:

public class CreateEditAccountModel
{
    [Required]
    [Display(Name = "Permission")]
    public int PermissionId { get; set; }
    public IEnumerable<SelectListItem> Permissions { get; set; }
}

Controller:

[HttpGet]
[Authorize]
public ActionResult EditAccount(int id)
{
    CreateEditAccountModel model = new CreateEditAccountModel();
    model.Permissions = PermissionsAll();
    return View("CreateEditAccount", model);
}

At this point if I put a break point on return line, the model.Permissions contains proper IEnumerable<SelectListItem> object with multiple items and only one, that has Selected = true.

View:

@using (Html.BeginForm())
{
    @Html.DropDownListFor(m => m.PermissionId, Model.Permissions)
}

Renders:

<select id="PermissionId" name="PermissionId">
    <option value="">-- Select --</option>
    <option value="1">Permission one</option>
    <option value="2">Permission two</option>
</select>

For some reason there is no selected attribute on any of the options and first option is selected.

Any help is appreciated.


UPDATE

It appears it has something to do with this article. To summarize the solution of this article, I need to make sure that the property name (first argument of @html.DropDownList) does not match any existing properties of the model. Can anybody explain why this is the case?

It renders drop down correctly when I write in the view something like this:

@Html.DropDownList("PermissionIdNotMatching", Model.Permissions)

However, it does not make any logical sense to do it since I actually want binder to be able to match the name of the select element to the model property. Otherwise I'd have to manually grab the value like this: Request.Form["PermissionIdNotMatching"];

Anybody have any thoughts?


SOLUTION

See accepted answer and the first comment to it.

Answer

Boris Parfenenkov picture Boris Parfenenkov · Nov 12, 2013

Ok, let's discuss about your example, when PermissionId was int. You posted model of type CreateEditAccountModel to view. When you created this model, PermissionId equal 0 (default value of int). And DropDownListFor in view get this value. Therefore you had no selected values. When you used string type, default value of PermissionId was null, therefore `DropDownListFor taken default value of SelectList.

In this case it's better to use int? or Nullable<int> type for PermissionId.