ASP.NET MVC DefaultModelBinder with nested lists

asp.net, asp.net-mvc, defaultmodelbinder

Solution

I eventually figured out why `DefaultModelBinder` wasn't picking up on the properties of `WorkUnit`: Because they weren't properties, they were fields. `DefaultModelBinder` only works with properties. Changing the class definition of `WorkUnit` and `Project` to use fields made everything click:

public class Project {
    public IList<WorkUnit> WorkUnits { get; set; }
    public string Name { get; set; }
}

public class WorkUnit {
    public DateTime Date { get; set; }
    public decimal RegularHours { get; set; }
    public decimal OvertimeHours { get; set; }
}

(Note: The source code in the original question had Project.Name defined as a field, in my actual code it was a property. This is why the Projects list was getting populated but WorkUnits wasn't.)

Problem

I have a View with a table representing an employee's timesheet. Days across the top, projects down the side, with each day/project intersection containing two values for regular hours and overtime. The (simplified) class definitions for the page model are: ``` public class TimesheetFormModel { public List<Project> Projects; // other things... } public class Project { public string Name; public List<WorkUnit> WorkUnits; } public class WorkUnit { public DateTime Date; public decimal RegularHours; public decimal OvertimeHours; } ``` The form elements on the page are named as follows in an attempt to get the DefaultModelBinder to pick up on them. ``` model.Projects[0].Name // "New Project" model.Projects[0].WorkUnits[0].Date // "5/23/2009 12:00:00 AM" model.Projects[0].WorkUnits[0].RegularHours // 0 model.Projects[0].WorkUnits[0].OvertimeHours // 0 model.Projects[0].WorkUnits[1].Date // "5/24/2009 12:00:00 AM" model.Projects[0].WorkUnits[1].RegularHours // 0 model.Projects[0].WorkUnits[1].OvertimeHours // 0 model.Projects[0].WorkUnits[2].Date // "5/25/2009 12:00:00 AM" model.Projects[0].WorkUnits[2].RegularHours // 0 model.Projects[0].WorkUnits[2].OvertimeHours // 0 // etc. ``` When the view is submitted however, the `model` parameter isn't being completely populated. `model.Projects` contains projects, but the `Project`'s `WorkUnits` field is empty. Does the `DefaultModelBinder` support nested collections like I'm trying to do? If not, what should I do?

Original source