2012-05-31 14 views
8

Empecé a usar MVC recientemente y estoy un poco decepcionado. En lugar de ayudarme, el marco se interpone en mi camino.¿Cómo ganar control sobre el enlace del modelo?

Estoy intentando escribir una acción de controlador como este (pseudo código)

ActionResult Save(long id, string whichForm) 
{ 
    if (whichForm == "A") 
    { 
     var vm = CreateModel(Request.Form); 
     if (!TryValidate(vm)) 
      return View(vm); 
     else 
      return RedirectToRoute("Success"); 
    } 
    else .... 
} 

Básicamente me gustaría tener el control sobre cuando mi vista-modelo se construye y cuando se valida. es posible? ¿Cómo puedo implementar el método CreateModel? Considere que puedo querer crear varios modelos de vista diferentes dentro de esta acción de controlador.

* Rant: Realmente no entiendo por qué el enlace y la validación del modelo de vista se mezclan en DefaultModelBinder. Parece que el código huele. Especialmente cuando es difícil anular este comportamiento.

+1

Gracias por los votos a favor, ¿desea dejar un comentario? :-) – Kugel

+0

+1 Tal vez no les gustó su * Rant pero tienen derecho a su opinión y no veo nada de malo en la pregunta. Si la pregunta resulta en buenas respuestas, entonces la pregunta está bien IMO. – AaronLS

Respuesta

16

Se pueden crear y unirse a un modelo existente a su discreción:

public ActionResult Save(long id, string whichForm) 
{ 
    if (whichForm == "A") 
    { 
     var vm = new FormAViewModel(); 

     if (!TryUpdateModel(vm)) 
      return View(vm); 
     else 
      return RedirectToRoute("Success"); 
    } 
    // else .... 
} 

You also have the option of creating your own IModelBinder, si desea tener un control completo sobre el proceso de unión. Puede reemplazar el archivador de modelo predeterminado o puede registrar implementaciones específicas de IModelBinder para tipos específicos. Sugeriría, sin embargo, que a menos que su lógica de enlace sea simple, probablemente querrá derivar su encuadernador de modelo personalizado desde el DefaultModelBinder y anular las partes que no le gustan.

Odio dejar un comentario troll-ish, pero 9 de cada 10 veces la razón por la que alguien siente que un framework se interpone en su camino es porque aún no entienden cómo usarla correctamente. Here is an article with general tips on model binding.

En cuanto a su queja: La validación y la vinculación son independientes, sin embargo, el encuadernador de modelo predeterminado activa la validación. La razón para esto es permitir que su aplicación maneje con gracia los problemas vinculados a valores faltantes/no válidos/incompletos, en lugar de permitir que el enlace falle silenciosamente o genere excepciones.

+0

Muchas gracias, me olvidé por completo del método TryUpdateModel. Y créanme, he estado buscando durante bastante tiempo y he leído todo sobre DefaultModelBinder y IModelBinder. También miré a través del código fuente de MVC ... – Kugel

0

Puede aprovechar la interfaz de IModelBinder y escribir un archivador de modelo personalizado completo. Aquí se explica bien. Esencialmente, esta interfaz expone un método "BindModel", donde puede controlar el comportamiento de enlace del modelo junto con la validación.

http://www.dotnetcurry.com/ShowArticle.aspx?ID=584

Sin embargo, esto podría complicar el asunto y que podría ponerse en código espagueti. Yo sugeriría una simple "Acción por modelo", si lo acepta. Para que pueda escribir algo como esto:

ActionResult SaveA(long id, AViewModel) 
{ 
     //.... Action to be conducted in case it is form A. 
} 
ActionResult SaveB(...., BViewModel) 
{ 
     //... Action to be conducted in case it is form B. 
} 


// Your view models can be structured for code reuse as well. 
class AViewModel { ... } 
class BViewModel : AViewModel { ... } 
+0

Lo siento, pero no entendió el punto de mi pregunta. – Kugel

Cuestiones relacionadas