Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

DropDownListFor - does not select "Selected" value

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.

like image 995
Dmitry Efimenko Avatar asked Mar 23 '12 01:03

Dmitry Efimenko


2 Answers

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.

like image 170
Boris Parfenenkov Avatar answered Nov 15 '22 19:11

Boris Parfenenkov


When you use @Html.DropDownListFor(m => m.PermissionId, Model.Permissions), please ensure the PermissionId is already set in your Model - that is the selected item / id. In addition, the model contains a 'selected' attribute:

var query = DatabaseContexts.Select(
            c => new SelectListItem
            {
                Value = c.Key,
                Text = c.Value,
                Selected = c.Key == currentUsed
            });

 PermissionId = that want to select;
 Permissions = query.AsEnumerable();

UPDATE:

here is a full sample of HttpGet:

In HomeController.cs:

[HttpGet]
public ActionResult EditAccount(int id)
{
    CreateEditAccountModel model = new CreateEditAccountModel();

    var permissionsAll = new List<SelectListItem>
         {
             new SelectListItem
                 {
                     Value = "",
                     Text = "--please select--",
                     Selected = false
                 },
             new SelectListItem
                 {
                     Value = "1",
                     Text = "Permission one",
                     Selected = true
                 },
             new SelectListItem
                 {
                     Value = "2",
                     Text = "Permission two",
                     Selected = false
                 }
         };
    model.PermissionId = 1; //add this line
    model.Permissions = permissionsAll; // PermissionsAll();// -- get data from services or anywhere....
    return View("EditAccount", model);
}

CreateEditAccountModel.cs:

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

}

EditAccount.cshtml:

@using MvcApplication1.Models
@model CreateEditAccountModel
@{
   ViewBag.Title = "EditAccount";
 }

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

Run the application and go to /home/editaccount/1, the dropdown will select "Permission one" by default.

I think the PermissionId must be type 'string' is, System.Web.Mvc.SelectedListItem.Value is 'string'

If you would like to do something when user selected item in the dropdown list, you may need [HttpPost].

BTW: this link is useful to you?

like image 4
xoyoja Avatar answered Nov 15 '22 21:11

xoyoja