How Does a Multiple Select List Work with Model Binding in ASP.NET Mvc

multiselect list model binding in asp.net mvc

You cannot bind a<select multiple> to a collection of complex objects, which is what your properties are. A <select multiple> posts back an array of simple values.

Your model needs 3 additional properties (note this assumes that the Id properties of your Building, Service and User model are typeof int)

public IEnumerable<int> SelectedBuildings { get; set; }
public IEnumerable<int> SelectedServices { get; set; }
public IEnumerable<int> SelectedUsers { get; set; }

In addition, you should be making the collection properties IEnumerable<SelectListItem>, and using new SelectList(...) in the controller, not the view to create the options, for example

public IEnumerable<SelectListItem> AllBuildings { get; set; }
....

and in the controller

vm.AllBuildings = new SelectList(_buildingService.GetBuildings(), "Id", "Name");

Finally, in order to bind correctly, you must use ListBoxFor(), not DropDownListFor() as explained in Why does the DropDownListFor lose the multiple selection after Submit but the ListBoxFor doesn't?

Your view code will now be

@Html.LabelFor(m => m.SelectedBuildings)
@Html.ListBoxFor(m => m.SelectedBuildings, Model.AllBuildings, new { @class="dropdown-menu" })
....
@Html.ListBoxFor(m => m.SelectedServices, Model.AllServices, new { @class="dropdown-menu" })
....

Asp.net MVC multiple select for List property

To create a <select multiple> you use the ListBoxFor() method in your view.

But your model needs two properties to generate a listbox, a IEnumerable<int> to bind the selected values to (assumes the ID proeprty of DanGrade is typeof int), and an IEnumerable<SelectListItem> to display the <option> elements.

You editing data, so always start with a view model

public class TeamMemberVM
{
public int? TeamMemberId { get; set; }
....
[Display(Name = "DanGrades")]
public IEnumerable<int> SelectedDanGrades { get; set; }
public IEnumerable<SelectListItem> DanGradesList { get; set; }
}

and your view will be

@model yourAssembly.TeamMemberVM
....
@Html.ListBoxFor(m => m.SelectedDanGrades, Model.DanGradesList, new { @class="dropdown" })

and your controller methods will be

public ActionResult Create()
{
TeamMemberVM model = new TeamMemberVM();
ConfigureViewModel(model);
// For an Edit method, your would set the existing selected items here
model.SelectedDanGrades = ...
return View(model);
}
public ActionResult Create(TeamMemberVM model)
{
if (!ModelState.IsValid)
{
ConfigureViewModel(model); // repopulate the SelectList
return View(model);
}
// model.SelectedDanGrades contains the ID's of the selected options
// Initialize an instance of your data model, set its properties based on the view model
// Save and redirect
}
private void ConfigureViewModel(TeamMemberVM model)
{
IEnumerable<DanGrade> danGrades = db.DanGrades();
model.DanGradesList = danGrades.Select(x => new SelectListItem
{
Value = x.DanGradeId.ToString(),
Text = x.??? // the name of the property you want to use for the display text
});
}

Note also that your view has a file input so your view model needs a HttpPostedFileBase property to bind the file to

public HttpPostedFileBase Image { get; set; }

and in the view

@Html.TextBoxFor(m => m.Image, { new type ="file" })

Selectlist binding for multiple rows of data in asp.net mvc

You can construct a SelectList on the fly for each row with your selected value and it should work.

@Html.DropDownListFor(x => x.MenuProducts[i].ContractTypeID, new SelectList(Model.ContractTypes, "Value", "Text", Model.MenuProducts[i].ContractTypeID), new { @class = "form-control" })

MVC 5 Multiselect List Values Not Binding to Model On Post

I noticed this right after I posted the question. The problem was having the setter protected. This prevented the binder from setting the value of the list.

ASP.NET MVC 5 Multi select not binding during POST

I have managed to find the correct and cleaner approach for accomplishing such tasks by utilizing the HTML helper methods inside my for loop and now the data are able to bind correctly during data-binding.

  @Html.HiddenFor(x => @Model.Roles[i].RoleId);
@Html.HiddenFor(x => @Model.Roles[i].RoleName);
@Html.CheckBoxFor(x => @Model.Roles[i].Selected);

ASP.NET Core: Problem binding model to a multiple Select List

I finally solve the issue doing the following:

I create the MultiSelectList item and send it to the view like this.

ReferralsController.cs

var consultants =  from c in _context.Consultant
select new
{
ConsultantID = c.ID,
c.FullName
};

ViewData["Consultants"] = new MultiSelectList(consultants, "ConsultantID", "FullName", referral.ReferralConsultants.Select(r => r.ConsultantID).ToArray());
return View(referral);

In the View

   <div class="form-group">
<label class="control-label d-inline">
Consultants
<select multiple name="selectedValues" class="form-control" asp-items="ViewBag.Consultants"></select>
</label>
</div>

This will send the selectedValues to my controller when I submit the form. Then I just need to get those values in my Edit [Post] and save them in the Database.

public async Task<IActionResult> Edit(int id, [Bind("ID,PatientID,RequesterID,DateIssued,DateRequested,Description,Type, Status")] Referral referral, string [] selectedValues)

MVC 5 Dropdownlistfor multiselect value binding in edit view

Since you have item values provided in ViewBag definition like this, which clearly indicates string values:

ViewBag.ItemsBag = db.Items.Select(v => new SelectListItem
{
Text = v.ItemName,
Value = v.ItemId.ToString() // implies all values are strings
});

Then the property to bound with DropDownListFor/ListBox must have List<string> or string[] type to be bound properly. Using ICollection<Item> will not bound because it is a complex object, while the helper requires value types (numeric types/string) to bound with.

Hence, you must create a property with type List<string> first:

public List<string> SelectedValues { get; set; }

And then use ListBoxFor helper with that property instead:

@Html.ListBoxFor(model => model.SelectedValues, new MultiSelectList(ViewBag.ItemsBag, "Value", "Text", Model.ItemsSelected.Select(x => x.Value)), new { @class = "form-control features-segments select2-multiselect-checkbox", multiple = "multiple" })

Note:

If ItemId property has int type (and all values are convertible to int), try with List<int>/int[] type instead of List<string>/string[]:

public List<int> SelectedValues { get; set; }


Related Topics



Leave a reply



Submit