Dubh
Dubh

Reputation: 55

MVC Model Binding failing when sorting viewmodel elements

I have a working scenario - My viewmodel contains a list of Employee objects.

List<Employee> Employees;

I populate this list by the following:

Employees = EmployeeService.GetAll().ToList();

This works fine. I can view the employees, update their data, post back and save to db.

However, when I try and sort the list of Employees in the viewmodel before sending to the view by replacing the code above with:

Employees = EmployeeService.GetAll().OrderBy(e=>e.Name).ToList();

The view is populated nicely with the ordered employee details. Unfortunately when I post back this viewmodel to the controller, the viewmodel.Employees is null / empty.

I'd appreciate any help if anyone has any ideas what I might be doing wrong here or why this is happening only when I sort.

Regards

Edit--

public ActionResult Index()
{
    EmployeesViewModel _viewModel = new EmployeesViewModel();
    return View(_viewModel);
}

[HttpPost]
public ActionResult Index(EmployeesViewModel viewModel)
{
    // HERE ** - viewModel.Employees is NULL
    EmployeesService.UpdateAllEmployees(viewModel);
    return View(viewModel);
}

Edit- Sample Markup --

for (int i = 0; i < Model.Employees.Count(); i++)
{
    @Html.HiddenFor(e => e.Employees[i].Id)
    @Html.HiddenFor(e => e.Employees[i].Name)
    <table>
        <tr>
            <td style = "width: 125px">
                @Model.Employees[i].Name
            </td>
            <td style = "width: 125px">
                @Html.CheckBoxFor(e => e.Employees[i].IsActive)
            </td>
        </tr>
    </table>
}    

Edit - Class Details

public class Employee
{
    public string Id { get; set; }
    public string Name { get; set; }
    public string InitialCode { get; set; }
    public bool IsActive { get; set; }

    public Employee()
    {

    }

}


public class EmployeesViewModel
{
    public List<Employee> Employees { get; set; }
    private readonly EmployeesService EmployeesService;

    public EmployeesViewModel()
    {
        Employees = new List<Employee>();
        EmployeesService = new EmployeesService();
        // Employees = EmployeesService.GetAll().ToList(); //THIS WORKS
        Employees = EmployeesService.GetAll().OrderBy(e=>e.Name).ToList();
    }
}

EmployeesService simply calls the DB Context and returns all records.

Upvotes: 0

Views: 1020

Answers (1)

danludwig
danludwig

Reputation: 47375

Your HTML form elements need to be rendered in a way that the DefaultModelBinder can correctly parse out the collection. Check out this: https://github.com/danludwig/BeginCollectionItem .

Also read this and this.

Upvotes: 1

Related Questions