Reputation: 2061
I'm having difficulty getting my MVC 5 multi select control to return the selected items in my ViewModel. It's as if the selected listbox items aren't binding to the available EmployeeCategoriesId collection, resulting in the return collection always being null.
ViewModel
public class EmployeeCreateViewModel
{
[Required]
public long OrganizationId { get; set; }
[Display(Name = "FirstName", ResourceType = typeof(Resources.Resources))]
[Required(ErrorMessageResourceType = typeof(Resources.Resources), ErrorMessageResourceName = "FirstNameRequired")]
public string FirstName { get; set; }
[Display(Name = "LastName", ResourceType = typeof(Resources.Resources))]
[Required(ErrorMessageResourceType = typeof(Resources.Resources), ErrorMessageResourceName = "LastNameRequired")]
public string LastName { get; set; }
[Display(Name = "DateOfBirth", ResourceType = typeof(Resources.Resources))]
[Required(ErrorMessageResourceType = typeof(Resources.Resources), ErrorMessageResourceName = "DateOfBirthRequired")]
public DateTime? DOB { get; set; }
//Employee categories selected from multi select list
public IEnumerable<int> EmployeeCategoriesId { get; set; }
//Employee categories for multi select list
[Display(Name = "Department", ResourceType = typeof(Resources.Resources))]
public List<EmployeeCategoryDefinition> SelectEmployeeCategories { get; set; }
}
Controller
// GET: Employees/Create
public ActionResult Create()
{
long organizationId = Convert.ToInt64(User.Identity.GetOrganizationId());
EmployeeCreateViewModel employeeCreateViewModel = new EmployeeCreateViewModel();
employeeCreateViewModel.SelectEmployeeCategories = db.EmployeeCategoryDefinition
.Where(ecat => ecat.OrganizationId == organizationId)
.OrderBy(ecat => ecat.Name)
.ToList();
return View(employeeCreateViewModel);
}
// POST: Employees/Create
// To protect from overposting attacks, please enable the specific properties you want to bind to, for
// more details see http://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Create([Bind(Include = "Id,OrganizationId,FirstName,LastName,DOB,CreatedUTC")] EmployeeCreateViewModel employeeCreateViewModel)
{
if (ModelState.IsValid)
{
Employee employee = new Employee(employeeCreateViewModel);
db.Employee.Add(employee);
await db.SaveChangesAsync();
return RedirectToAction("Index");
}
//Get Employee categories from DB - List binding lost at post back
long organizationId = Convert.ToInt64(User.Identity.GetOrganizationId());
employeeCreateViewModel.SelectEmployeeCategories = db.EmployeeCategoryDefinition
.Where(ecat => ecat.OrganizationId == organizationId)
.OrderBy(ecat => ecat.Name)
.ToList();
return View(employeeCreateViewModel);
}
View (enclosed within a BeginForm)
<div class="col-sm-10">
@Html.ListBoxFor(m => m.EmployeeCategoriesId,
new MultiSelectList(Model.SelectEmployeeCategories, "Id", "Name"),
new { @class = "chosen-select", @style = "width:350px;", @data_placeholder = "PH" })
</div>
Can you see why the returning "EmployeeCategoriesId" in my ViewModel is always returning null to the POST controller action? The ListBox does populate with the options passed to the view.
Upvotes: 0
Views: 498
Reputation:
You have a [Bind(Include="..")]
attribute which is specifically excluding the property EmployeeCategoriesId
from binding.
Since you are using a view model, which is supposed to represent just the properties you want to edit in the view, you should not even include the BindAttribute
(by default all properties are bound)
Upvotes: 1