2012-04-20 10 views
7

Actualmente estoy usando ViewModels para separar mis vistas de la estructura del modelo real.Modelo "Merge" y ViewModel con o sin AutoMapper?

Por ejemplo, tengo una entidad de persistencia de usuario y un MiPerfil de modelo de vista que contiene toda la información que un usuario puede cambiar por sí mismo. Para la conversión de Usuario a Mi Perfil, estoy usando Automapper.

Ahora, después de que un usuario publique su información (modificada), debo guardarla. Pero la información en ViewModel no está completa, y cuando AutoMapper crea una entidad de persistencia del Usuario desde el ViewModel, se pierde información importante.

No quiero exponer esta información a la capa de vista, especialmente no con elementos de formulario ocultos.

Así que necesito una forma de combinar un ViewModel en una entidad de persistencia. ¿Puedo hacer eso con AutoMapper, o tengo que hacerlo manualmente?

Ejemplo:

Mi clase de usuario contiene la identificación, nombre, apellido, nombre de usuario y contraseña. El usuario solo debe editar su Nombre y Apellido en su perfil. Por lo tanto, mi ProfileViewModel contiene ID, Firstname y Lastname. Después de volver a publicar la información del formulario, Automapper crea un objeto User desde el ProfileViewModel transferido, y en este objeto solo se establecen ID, Firstname y Lastname. Al alimentar esta entidad a mi repositorio, he perdido la información de nombre de usuario y contraseña.

+0

Por qué la información no es completa? ¿Podrías publicar un fragmento de código? –

+0

Estaba usando Mapper.Map (modelo) en lugar de buscar primero la entidad de usuario y luego usar Mapper.Map (usuario, modelo) – ckonig

Respuesta

12

Así que necesito una forma de combinar un ViewModel en una entidad de persistencia. ¿Puedo hacer con AutoMapper, o tengo que hacerlo manualmente?

Sí, puede hacerlo con AutoMapper. Por ejemplo:

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

public class ViewModel 
{ 
    public string Name { get; set; } 
} 

class Program 
{ 
    static void Main() 
    { 
     // define a map (ideally once per appdomain => usually goes in Application_Start) 
     Mapper.CreateMap<ViewModel, Model>(); 

     // fetch an entity from a db or something 
     var model = new Model 
     { 
      Id = 5, 
      Name = "foo" 
     }; 

     // we get that from the view. It contains only a subset of the 
     // entity properties 
     var viewModel = new ViewModel 
     { 
      Name = "bar" 
     }; 

     // Now we merge the view model properties into the model 
     Mapper.Map(viewModel, model); 

     // at this stage the model.Id stays unchanged because 
     // there's no Id property in the view model 
     Console.WriteLine(model.Id); 

     // and the name has been overwritten 
     Console.WriteLine(model.Name); 
    } 
} 

impresiones:

5 
bar 

y traducir esto en un patrón típico ASP.NET MVC:

[HttpPost] 
public ActionResult Update(MyViewModel viewModel) 
{ 
    if (!ModelState.IsValid) 
    { 
     // validation failed => redisplay view 
     return View(viewModel); 
    } 

    // fetch the domain entity that we want to udpate 
    DomainModel model = _repository.Get(viewModel.Id); 

    // now merge the properties 
    Mapper.Map(viewModel, model); 

    // update the domain model 
    _repository.Update(mdoel); 

    return RedirectToAction("Success"); 
} 
+0

¡Bien, eso tiene sentido ahora! Y se ve mucho mejor que utilizar un método de capa negra UpdateModel(). – ckonig

Cuestiones relacionadas