SWa
SWa

Reputation: 4363

DropDownListFor not binding value

I have the following ViewModel

    public class ContactAddViewModel
    {
        string _title;
        public ContactAddViewModel()
        {
            var titles = new List<SelectListItem>()
            {
                new SelectListItem() { Value = "Mr", Text= "Mr" },
                new SelectListItem() { Value= "Miss", Text="Miss" },
                new SelectListItem() { Value = "Mrs", Text= "Mrs" },
                new SelectListItem() { Value = "Ms", Text = "Ms" },
                new SelectListItem() { Value = "Dr", Text = "Dr" }
            };

            Titles = titles;
        }

        [Required]
        [Display(Name = "Title")]
        public string Title { get; set; }
        public IEnumerable<SelectListItem> Titles { get; set; }
...

Called in a controller:

  var ctc = new ContactAddViewModel()
            {
                Title = contact.Title.Trim()
            };

  return View(ctc);

Then in the view:

<div class="form-group col-md-2">
    @Html.LabelFor(m => m.Title)
    @Html.DropDownListFor(m => m.Title, Model.Titles, string.Empty, new { @class = "form-control placeholder-no-fix" })
    @Html.ValidationMessageFor(m => m.Title, "", new { @class = "help-block" })
</div>

However none of the options are selected. I've verified that the title is correct, I've even tried manually setting:

[Required]
[Display(Name = "Title")]
public string Title
{
    get { return _title; }
    set
    {
        _title = value;
        foreach(var t in Titles)
        {
            if(t.Value == _title)
            {
                t.Selected = true;
            }
        }
    }
}

When debugging in the view, the correct SelectListItem has the Selected property set to true, however it isn't selected in the final markup.

Where am I going wrong? - I have other dropdowns in the model (that have numeric values if it makes any difference) that bind correctly.

Upvotes: 1

Views: 2322

Answers (1)

Chris Pratt
Chris Pratt

Reputation: 239220

This one's going to make you want to put your head through a wall. Do you happen to be using ViewBag.Title to set the page title in your view? That's pretty common.

Well, the first thing you need to understand is that setting the Selected property of a SelectListItem does absolute jack all in MVC. Razor automatically chooses which item to mark as selected based on ModelState, and will override anything you've manually set as selected.

ModelState is composed of values from Request, ViewData/ViewBag and finally Model. Long and short, if you have a key in Request, or important to your issue here, a ViewBag member with the same name as your property, that value will be the set value for the HTML Razor generated. I'd imagine ViewBag.Title doesn't match anything in your Titles enumerable, so that's why it's unset. You'll need to name this property something else or change your ViewBag.Title to something like ViewBag.PageTitle.

Upvotes: 8

Related Questions