Digbyswift
Digbyswift

Reputation: 10410

Selected value not set on DropDownListFor() in MVC4

It seems like this question has been asked too many times. But this is driving me nuts.

This is my (simplified) model.

public class UserEditModel
{
    [Required]
    public string Title { get; set; }

    private IEnumerable<SelectListItem> _titleList;
    public IEnumerable<SelectListItem> TitleList
    {
        get { return _titleList.Select(x => new SelectListItem {
                            Selected = (x.Value == Title), 
                            Text = x.Text,
                            Value = x.Value
                        });
        }
        set { _titleList = value; }
    }
}

The Text and Value properties of each SelectListItem in the TitleList member are identical. For example:

new SelectListItem { Text = "Mr", Value = "Mr"  }

When the following code is posted, the correct Title value is bound to the model, but whenever the model is pushed to the view in response to a POST or a GET, the selected value is not set on the dropdownlist, even though all the intellisense shows that the correct values are present.

@Html.DropDownListFor(x => x.Title, Model.TitleList)

I have ensured that the code is correct based on several articles and several SO answers, so I am stumped.

Any suggestions?

Update:

For completeness, this is the action and supporting method:

[HttpGet]
public ActionResult Edit(int id)
{
    var user = _userService.Get(id);

    var model = new UserEditModel()
    {
        ...
        Title = user.Title,
        TitleList = ListTitles()
    };

    return View(model);
}

private IEnumerable<SelectListItem> ListTitles()
{
    var items = new[] {
            new SelectListItem() {Text = "Mr", Value = "Mr" },
            new SelectListItem() {Text = "Mrs", Value = "Mrs"},
            new SelectListItem() {Text = "Ms", Value = "Ms"},
            new SelectListItem() {Text = "Miss", Value = "Miss"},
            new SelectListItem() {Text = "Professor", Value = "Professor"},
            new SelectListItem() {Text = "Dr", Value = "Dr" }
        };

    return items;
}

As you see there is nothing fancy, just a straightforward implementation.

Upvotes: 3

Views: 3895

Answers (3)

Digbyswift
Digbyswift

Reputation: 10410

Well, it seems there is actually nothing wrong with the code, just the name of the Title property in the model.

It looks like Title is a reserved word and replacing it with TitleX or more appropriately Salutation makes everything work fine.

Upvotes: 2

Tim
Tim

Reputation: 89

Are you sure you retrieve the selectlist item appropriately in the controller? For me it is working fine. I would use a get method instead of a property ( GetTitleList(string value) ), to avoid mistakes in getting the selectionlist farther along in your code.

Upvotes: 0

Mathew Thompson
Mathew Thompson

Reputation: 56459

You need to add ModelState.Clear() because by default when returning a view from a post action, it thinks it has failed validation, so uses the values in ModelState and not the values in the Model. Many people think this is actually a bug in MVC, but it's by design:

ASP.NET MVC assumes that if you’re rendering a View in response to a HttpPost, and you’re using the Html Helpers, then you are most likely to be redisplaying a form that has failed validation. Therefore, the Html Helpers actually check in ModelState for the value to display in a field before they look in the Model. This enables them to redisplay erroneous data that was entered by the user, and a matching error message if needed.

Link

Upvotes: 2

Related Questions