2009-04-03 12 views
7

Estoy tratando de escribir un encuadernador de modelo personalizado, pero estoy teniendo grandes dificultades para tratar de averiguar cómo vincular objetos compuestos complejos.Encuadernador de modelo personalizado para objetos compuestos complejos AYUDA

esta es la clase que estoy tratando de obligar a:

public class Fund 
{ 
     public int Id { get; set; } 
     public string Name { get; set; } 
     public List<FundAllocation> FundAllocations { get; set; } 
} 

y esto es cómo mi intento de escribir la carpeta de encargo se parece a:

public class FundModelBinder : IModelBinder 
{ 
    public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) 
    { 
     throw new NotImplementedException(); 
    } 

    public object GetValue(ControllerContext controllerContext, string modelName, Type modelType, ModelStateDictionary modelState) 
    { 
     var fund = new Fund(); 

     fund.Id = int.Parse(controllerContext.HttpContext.Request.Form["Id"]); 
     fund.Name = controllerContext.HttpContext.Request.Form["Name"]; 

     //i don't know how to bind to the list property :(
     fund.FundItems[0].Catalogue.Id = controllerContext.HttpContext.Request.Form["FundItem.Catalogue.Id"]; 
     return fund; 
    } 
} 

¿Ideas

gracias Tony

+0

Acabo de publicar una pregunta y finalmente descubrí una solución para este mismo tipo de problema. Para aquellos interesados, es posible que desee consultar el siguiente enlace: [http://stackoverflow.com/questions/1077481/how-do-i-pass-a-dictionary-as-a-parameter-to-an-actionresult -method-from-jquery-a] (http://stackoverflow.com/questions/1077481/how-do-i-pass-a-dictionary-as-a-parameter-to-an-actionresult-method-from- jquery-a) –

Respuesta

3

He estado gastando demasiado en esto exacto s ame cosa últimamente!

Sin ver su formulario HTML, supongo que solo devuelve los resultados de la selección de una lista de selección múltiple o algo así? Si es así, su formulario solo está devolviendo un montón de enteros en lugar de devolver su objeto FundAllocations hidratado. Si desea hacer eso, en su ModelBinder personalizado, necesitará hacer su propia búsqueda e hidratar el objeto usted mismo.

Algo así como:

fund.FundAllocations = 
     repository.Where(f => 
     controllerContext.HttpContext.Request.Form["FundItem.Catalogue.Id"].Contains(f.Id.ToString()); 

Por supuesto, mi LINQ es única por ejemplo y que, obviamente, puede recuperar los datos de cualquier forma que desee. Por cierto, y sé que no responde a tu pregunta, pero después de mucho menospreciar he decidido que para objetos complejos, lo mejor es usar un modelo de vista y tener el enlace predeterminado de ModelBinder para eso y luego, si es necesario, hidratarlo el modelo que representa mi entidad. Hay una serie de problemas con los que me encontré y que hicieron de esta la mejor opción, no te aburriré con ellos ahora, pero me alegra extrapolar si lo deseas.

La última Herding Code podcast es una gran discusión de esto al igual que K Scott Allen's Putting the M in MVC blog posts.

8

¿Realmente necesita implementar un ModelBinder personalizado aquí? El aglutinante defecto puede hacer lo que tiene (ya que puede poblar colecciones y objetos complejos):

permite decir que su acción del controlador se ve así:

public ActionResult SomeAction(Fund fund) 
{ 
    //do some stuff 
    return View(); 
} 

Y HTML contiene esto:

<input type="text" name="fund.Id" value="1" /> 
<input type="text" name="fund.Name" value="SomeName" /> 

<input type="text" name="fund.FundAllocations.Index" value="0" /> 
<input type="text" name="fund.FundAllocations[0].SomeProperty" value="abc" /> 

<input type="text" name="fund.FundAllocations.Index" value="1" /> 
<input type="text" name="fund.FundAllocations[1].SomeProperty" value="xyz" /> 

La carpeta de modelo predeterminada debe inicializar su objeto de fondo con 2 elementos en la Lista de asignaciones de fondos (no sé cómo se ve su clase FundAllocation, así que hice una sola propiedad "SomeProperty"). Solo asegúrate de incluir esos elementos "fund.FundAllocations.Index" (que la carpeta predeterminada busca para su propio uso), que me dieron cuando intenté que esto funcionara).

+0

JonoW: ¿tiene un enlace para obtener una buena documentación del archivador modelo estándar, o simplemente miró la fuente? –

+0

Will, lo siento, no tengo un enlace a ninguna documentación oficial, realmente estaba siguiendo el consejo de Phil Haack en su blog, ya que tenía un problema similar - http://haacked.com/archive/2008/10 /23/model-binding-to-a-list.aspx. Puede haber una forma mejor de hacerlo en 1.0, no estoy seguro ... – JonoW

+0

Está en lo cierto, no necesita un archivador de modelo personalizado. Puede hacerlo manipulando el campo de nombre como se demostró anteriormente. – MedicineMan

Cuestiones relacionadas