Extendiendo ModelBinder de ASP.Net MVC

A raíz de una pregunta que hice en el foro de S#arp, fue que surgió este tema. El problema es que en un modelo MVC la vista es totalmente agnóstica con respecto al modelo de dominio. No obstante ASP.Net MVC introduce un concepto denominado ModelBinder cuyo funcionamiento sería algo así; supongamos que en una vista que sirve para llenar los datos de una persona tenemos 3 inputs llamados Persona.Nombre, Persona.Apellido y Persona.Domicilio. Mi action method podría ser de la siguiente forma:
//Sin usar model binder.
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult GuardarPersona(string nombre, string apellido, string domicilio)
{
    //bla-bla-bla
    return View();
}

//Usando model binder.
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult GuardarPersona(Persona personaAGuardar)
{
    //bla-bla-bla
    return View();
}
La ventaja de usar el modelbinder en este caso es que automáticamente obtengo una instancia de la clase del modelo con todas sus propiedades cargadas. El problema empieza cuando tengo una clase un poco mas complejas con propiedades no triviales (no es string, int, decimal, etc.) Para los fines del ejemplo, supongamos una vista de este tipo: pantalla El dominio tiene esta pinta:
    public class User
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string UserName { get; set; }
    public string Password { get; set; }
    public Country Country { get; set; }
    public IEnumerable<Sport> SportsPreferences { get; set; }
}

public class Country
{
    public int Id { get; set; }
    public string Name { get; set; }
}

public class Sport
{
    public int Id { get; set; }
    public string Name { get; set; }
}
DefaultModelBinder no puede con las propiedades Country y SportsPreferences y sería muy POSITIVO que si pudiera. Un problema-muchos caminos El problema radica en que la vista no tiene información acerca de países ni deportes, mas que la necesaria para mostrarle al usuario esos datos y permitirle saber al controlador cuales son los que el usuario selecciono. A grandes rasgos las soluciones que se plantean son las siguientes;
  • Que la vista contenga instancias reales sobre países y deportes.
  • Que la acción en el controlador reciba un DTO de Usuario con propiedades triviales y a partir de él construir un objeto de dominio.
  • Crear un model binder especifico para cada situación, ya sea implementando IModelBinder o heredando de DefaultModelBinder.
  • Crear un model binder genérico que sepa como resolver propiedades mas complejas ubicando la instancia a través de su respectivo repositorio (u otro método proporcionado) o creando una instancia nueva en caso de ser necesario.
Estoy muy entusiasmado con la opción 4 si bien es el camino mas engorroso. Este model binder de alguna manera resolvería la propiedad User.Country dado que el usuario ha seleccionado un país cuyo ID=’AR’ (es decir en el htmlform tenemos ‘AR’) buscando a través del método indicado dicha instancia. Intentaría que este Modelbinder no este ligado a un repositorio en concreto, ni a una forma particular de obtener las instancias. Este es el concepto: Concept2

blog comments powered by Disqus
  • Categories

  • Archives