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
Display Simple HTML in a Native Blackberry Application
Display Element as Preformatted Text via CSS
How to Test a Website for Retina on Windows Without an Actual Retina Display
Span Inside Anchor or Anchor Inside Span or Doesn't Matter
How to See Which Srcset Image a Browser Is Using with Browser Developer Tools
Is There a Web Service for Converting HTML to Pdf
Text Not Wrapping in Paragraph Element
Svg Foreignobject Contents Do Not Display Unless Plain Text
Using Cm/Mm on The CSS of a Web App That Replicates Paper Interaction Is a Good Practice
HTML5 Canvas Scrolling Vertically and Horizontally
CSS Grids: Align Square Cells with Container Edges with Consistent Grid Gap
Responsive Video Iframes (Keeping Aspect Ratio) with Only CSS
Post Values from a Multiple Select
How to Make The HTML Link Activated by Clicking on The <Li>
Why Doesn't Margin:Auto Center an Image
How to Force Horizontal Scrolling in an HTML List Using CSS
Bootstrap 3 Truncate Long Text Inside Rows of a Table in a Responsive Way