Search code examples
c#asp.net-coreasp.net-core-tag-helpers

Listbox POSTing but not populating model


I have a model that looks like this:

    public List<SelectListItem> Interests { get; } = new List<SelectListItem>
    {
        new SelectListItem { Value = "Buyers Agent", Text = "Buyers Agent" },
        new SelectListItem { Value = "Showing Agent", Text = "Showing Agent" },
        new SelectListItem { Value = "Realtor Associate", Text = "Realtor Associate"  },
        new SelectListItem { Value = "Transaction Coordinator", Text = "Transaction Coordinator"  },
        new SelectListItem { Value = "Guest Blog Writer", Text = "Guest Blog Writer"  }
    };

The view looks like this:

            <div>
                <label for="Interests" class="control-label col-sm-2" style="padding-left: 0px;">Your Interests: </label>
                <select asp-for="Interests" asp-items="Model.Interests"></select> 
            </div>

And renders to this:

<div>
   <label for="Interests" class="control-label col-sm-2" style="padding-left: 0px;">Your Interests: </label>
   <select id="Interests" multiple="multiple" name="Interests">
        <option value="Buyers Agent">Buyers Agent</option>
        <option value="Showing Agent">Showing Agent</option>
        <option value="Realtor Associate">Realtor Associate</option>
        <option value="Transaction Coordinator">Transaction Coordinator</option>
        <option value="Guest Blog Writer">Guest Blog Writer</option>
    </select> 
</div>

If items are selected, they are POSTed back, but controller call shows 0 items in the 'Interests' property of the model. The controller looks like this:

    [HttpGet]
    [AllowAnonymous]
    public IActionResult Interest()
    {
        var model = new InterestFormViewModel();

        return View(model);
    }

    [HttpPost]
    [AllowAnonymous]
    [ValidateAntiForgeryToken]
    public IActionResult Interest(InterestFormViewModel model)
    {
        // A breakpoint and watch show model.Interests to have a count of 0.

        return View("HRThanks");
    }

I must be overlooking something obvious, can someone tell me what it might be? Thanks!


Solution

  • The <select> element posts back a single value (or an array of simple values in the case of a <select multiple>. You cannot bind your select to Interests because its is a collection of complex objects (SelectListItem).

    Your model needs a property to bind the selected value(s) to. If you want a dropdownlist, then (say)

    public string SelectedItem { get; set; }
    

    and in the view

    <label for="SelectedItem" ...</label>
    <select asp-for="SelectedItem" asp-items="Model.Interests"></select> 
    

    or if you want a listbox, then

    public IEnumerable<string> SelectedItems { get; set; }
    

    and in the view

    <select asp-for="SelectedItems" asp-items="Model.Interests"></select>
    

    Note that of you set the value of SelectedItem (or SelectedItems) in the GET method before you pass the model to the view, and its value(s) match one of the options, then that option(s) will be selected initially.