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.

Related posts

Recent Viewed