ASP.NET MVC DefaultModelBinder con listas anidadas
-
05-07-2019 - |
Pregunta
Tengo una vista con una tabla que representa la hoja de tiempo de un empleado. Días en la parte superior, proyectos por el lado, con cada intersección entre el día y el proyecto que contiene dos valores para horas regulares y horas extra.
Las definiciones de clase (simplificadas) para el modelo de página son:
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;
}
Los elementos del formulario en la página se nombran de la siguiente manera para intentar que DefaultModelBinder los recupere.
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.
Sin embargo, cuando se envía la vista, el parámetro model
no se está completando completamente. model.Projects
contiene proyectos, pero el campo Project
de WorkUnits
está vacío. ¿El DefaultModelBinder
admite colecciones anidadas como lo estoy intentando hacer? Si no, ¿qué debo hacer?
Solución
Finalmente, descubrí por qué DefaultModelBinder
no estaba captando las propiedades de WorkUnit
: como no eran propiedades , eran campos . DefaultModelBinder
solo funciona con propiedades. Cambiar la definición de clase de WorkUnit
y Project
para usar los campos hizo que todo hiciera clic en:
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; }
}
(Nota: el código fuente en la pregunta original tenía Project.Name definido como un campo, en mi código real era una propiedad. Es por eso que la lista de Proyectos se estaba llenando pero WorkUnits no).