Search code examples
asp.net-mvchtml-selectdefaultselectlist

Selected item in SelectList not being displayed in view drop-down


I have an asp.net MVC application in which I have a Razor view for creating a new event. On the form is a drop-down list of seasons for the user to select from. I would like the current season to be pre-selected in this list as a default.

I have set up two seasons:

Season 1 is for 2020-2021 and has its IsCurrent property set to False; Season 2 is for 2021-2022 and has its IsCurrent property set to True

Controller code...

ViewData["Seasons"] = new SelectList(_context.Seasons, "ID", "SeasonName",_context.Seasons.Where(s => s.IsCurrent==true));

View...

<select asp-for="SeasonID" class="form-control" asp-items="ViewBag.Seasons"></select>

When I run this, I am expecting to see the season 2021-2022 pre-selected in the drop-down, but it just shows 2020-2021 (being the first in the list).

This seems like it should be so simple - can someone please tell me where I'm going wrong?


Solution

  • This one has bitten me a few times in the past, all the way back to MVC 3 or so.

    Basically, if you're passing a model to your view (i.e. using a @model MyTypeOfViewModel directive) and binding a select to a property on that model, then the selected value of the select list is the value of the property you are binding to on your view model. Setting the selected item in a select list directly will be ignored.

    In your case, it's SeasonID from this:

    <select asp-for="SeasonID" ...>
    

    So for you to select Season 2, you'd need to set the value of the SeasonID property on your view model to the ID of Season 2:

    var viewModel = new SeasonViewModel
    {
        SeasonID = // Season 2's SeasonID
    }
    

    However, if you're not binding the value of the select directly, creating the select like this:

    // Notice I've not specified `asp-for`.
    <select class="form-control" asp-items="ViewBag.Seasons"></select>
    

    will use the selected value you set when creating the SelectList. That said, your code to do that is currently slightly wrong. It should be:

    var selected = _context.Seasons
        .Where(s => s.IsCurrent == true)
        .FirstOrDefault();
    ViewData["Seasons"] = new SelectList(
                    _context.Seasons,
                    "ID",
                    "SeasonName",
                    // It needs to be the actual value of the field, not the season's object.
                    selected?.ID.ToString());
    

    In short, if you want to bind to your SeasonID property, create your SelectList, without selecting a value, like so:

    ViewData["Seasons"] = new SelectList(
                _context.Seasons,
                "ID",
                "SeasonName");
    

    Then set the selected value on the view model itself, and the asp-for attribute on the select will do the rest.