Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SelectListItem selected = true not working in view

Tags:

c#

asp.net-mvc

I have a gender select field (--Select--, Male, Female) and I'm populating that in my controller. When the page loads, I want the gender that is selected in the model pm.Gender to be automatically selected when the page loads.

The values from pm.Gender come back as:

  • " "
  • "M"
  • "F"

View:

<%: Model.Gender %>
<%: Html.DropDownListFor(m => m.Gender, (IEnumerable<SelectListItem>)ViewData["gender"], new { @class = "span2" })%>

Controller:

gender = new[] { "Select", "Male", "Female" };
List<SelectListItem> genderselectList = new List<SelectListItem>();
foreach (string item in gender)
{
   SelectListItem sli = new SelectListItem { Text = item, Value = item };

   if (item.Trim().StartsWith(pm.Gender))
      sli.Selected = true;

   genderselectList.Add(sli);
}

ViewData["gender"] = genderselectList;

After debugging the application, I can see that genderselectList contains the proper data with Selected = true for the proper value that is supposed to be selected. But when the page loads, nothing is selected in the dropdown list that was supposed to be generated with the Html.DropDownListFor.

Edit: Does not work in any browser.

Anyone know what could be causing this problem? Any help would be appreciated.

Cheers.

EDIT: (After implementing Kaf's solution)
Ok so this is what I'm doing after implementing Kaf's solution.

View:

<%: Html.DropDownListFor(m => m.Gender, (SelectList)(ViewData["gender"]), new { @class = "span2" }) %>

Controller:

gender = new[] { "Select", "Male", "Female" };
List<SelectList> genderselectList = new List<SelectList>();
foreach (string item in gender)
{
    SelectList sli;

    if (item.Trim().StartsWith(pm.Gender))
        sli = new SelectList(GetGender(), item, item, item); 
    else
        sli = new SelectList(GetGender(), item, item);
        //without selectedValue

    genderselectList.Add(sli);
}

ViewData["gender"] = genderselectList;

When I do that, I get the following exception:
Unable to cast object of type 'System.Collections.Generic.List`1[System.Web.Mvc.SelectList]' to type 'System.Web.Mvc.SelectList'.

Anyone know what I'm doing wrong?

like image 357
Farhan Ahmad Avatar asked May 11 '12 14:05

Farhan Ahmad


People also ask

What is SelectListItem MVC?

SelectListItem is a class which represents the selected item in an instance of the System. Web. Mvc.


2 Answers

I suggest it's better if you use strongly typed property for SelectList (rather than using ViewBag/ViewData). I believe what you are expecting is that your dropdownlist to be pre-selected with the gender selection made in the model. Here is a solution (code is not 100% clean. But this will work)

Model

public class TestModel
{
    public string Gender { get; set; }

    public IEnumerable<SelectListItem> GenderList
    {
        get
        {
            List<SelectListItem> list = new List<SelectListItem> { new SelectListItem() { Text = "Select", Value = "Select" }, new SelectListItem() { Text = "Male", Value = "Male" }, new SelectListItem() { Text = "Female", Value = "Female" } };
            return list.Select(l => new SelectListItem { Selected = (l.Value == Gender), Text = l.Text, Value = l.Value });
        }
    }
}

Controller Action

public ActionResult MyView()
{
    TestModel m = new TestModel();
    m.Gender = "Female";
    return View(m);
}

MyView.cshtml

@model TestModel

@{
    ViewBag.Title = "MyView";
}

<h2>MyView</h2>
@using (Html.BeginForm())
{
    <div>
          @Html.DropDownListFor(model => model.Gender, Model.GenderList)
    </div>
}

OUTPUT

dropdown with 'Female' option selected

enter image description here

EDIT

Based on comments find below links to sample projects

1) https://github.com/prashanth-t/DropdownDemo_BareBones (Using the MVC 4 empty template. Smaller file size with bare minimum)

2) https://github.com/prashanth-t/DropdownDemo (Using the MVC 4 internet application template. Bigger file size)

like image 97
Prashanth Thurairatnam Avatar answered Sep 25 '22 15:09

Prashanth Thurairatnam


This is a known bug in ASP.NET MVC Razor View. As per the known bug documentation

"The reason behind this problem is that asp.net MVC first looks for a match between the name of the drop down and property on the model. If there’s a match, the selected value of the SelectList is overridden. Changing the name of the drop down is all it takes to remedy the issue."

I'm here giving a small example which you can use to test the resolution.

 var paymentTypeList = new List<SelectListItem>
                {
                    new SelectListItem { Text = "Select Payment Type", Value = "NA" },
                    new SelectListItem { Text = "Card", Value = "Card" },
                    new SelectListItem { Text = "Paytm Wallet", Value = "Paytm Wallet" },
                    new SelectListItem { Text = "Cash", Value = "Cash", Selected = true },
                    new SelectListItem { Text = "Credit", Value = "Credit" },
                    new SelectListItem { Text = "Other", Value = "Other" }
                };
 ViewBag.paymentTypeList = paymentTypeList;

Resolution Option 1 (Easiest) - Change the Name of declaration id of select list id in MVC view e.g

@Html.DropDownList("paymentTypeListNew", (List<SelectListItem>)ViewBag.paymentTypeList, new { @class = "form-control select2 select1" })

Resolution 2: (Use only single constructor of @Html.DropDownList that matches viewbag/viewdata property)

To ensure that selected item (cash in this example) gets selected do the following in MVC Razor View. Use only the following constructor without any CSS or new object values

 @Html.DropDownList("paymentTypeList") 

Now if you are worried that you cannot initialize the CSS then you need to initialize the css programitally. For example if you are using Jquery then can you can use

$("#paymentTypeList").addClass("form-control");
            $("#paymentTypeList").addClass("select2");
like image 34
vibs2006 Avatar answered Sep 23 '22 15:09

vibs2006