2011-01-30 14 views
10

Estoy usando asp.net mvc 3, anotaciones de datos y mapeador automático.¿Cómo hacer las listas en un modelo de vista? + dataannotaciones

Quiero tener todas mis anotaciones en las propiedades en mi modelo de vista una vez que las propiedades pasan la validación Utilizo el mapeador automático para asignarlo de nuevo a mi objeto de dominio.

Tengo un modelo de vista que tiene propiedades de las que quiero tener una colección, ya que quiero generar una tabla a partir de ellas. También quiero usarlos más tarde para usarlos como formulario para agregar filas a esta tabla.

Entonces, ¿qué debo hacer? ¿Cómo tomo estas propiedades y hago una colección de ellas?

public class UserViewModel() 
{ 
    [Required()] 
    public string UserName = {get; set;} 
    [Required()] 
    public string FirstName = {get; set;} 
    [Required()] 
    public string LastName = {get; set;} 
} 

Quiero utilizar estas propiedades para generar mi tabla y ser utilizada para un formulario.

La única cosa que puedo pensar en está haciendo esto

public class AddUserViewModel() 
    { 
     [Required()] 
     public string UserName = {get; set;} 
     [Required()] 
     public string FirstName = {get; set;} 
     [Required()] 
     public string LastName = {get; set;} 
    } 

    public class UserViewModel() 
    { 
     public List<User> Users {get; set;} 
     public AddUserViewModel {get; set;} 

     public UserViewModel() 
     { 
      Users = new List<Users>(); 
     } 
    } 

Así que básicamente tienen como modelo vista separada que está encerrado en otro modelo de vista que contiene una lista de usuarios (mi modelo de dominio)

De esta manera utilizo mi modelo de dominio para generar la tabla y mi AddUserViewModel para agregar usuarios.

Parece un poco redundante, así que no estoy seguro de si hay una mejor manera.

Editar

tengo algo como esto

var viewModel = new UserViewModel(); 
List<Users> users= UserService.GetAllUsers(); 
viewModel = Mapper.Map<Users, UserViewModel>(users); 
return View("Index", viewModel); 

También trató

var viewModel = new UserViewModel(); 
List<Users> users= UserService.GetAllUsers(); 
viewModel.AddUserViewModel = Mapper.Map<Users, AddUserViewModel>(users); 
return View("Index", viewModel); 

Editar 2

tengo esto y compila pero Obtengo este error

 SomeViewModel viewModel = new SomeViewModel();  
     List<User> users= userService.GetAllUsers(); 
     viewModel.UserViewModel = Mapper.Map<List<User>, List<UserViewModel>>(users); 
     return View("Index", viewModel); 


Trying to map Domain.User to ViewModels.UserViewModel. 
Missing type map configuration or unsupported mapping. 
Exception of type 'AutoMapper.AutoMapperMappingException' was thrown. 
+0

No entiendo totalmente su pregunta ni lo que está tratando de lograr. –

+0

@Darin Dimitrov - Ya que era un error tipográfico. Eso está corregido ahora. Estoy tratando de descubrir cómo puedo seguir usando las anotaciones de datos en el modelo de vista, pero también puedo devolver una lista de mis objetos de dominio, posiblemente sin duplicar el código dos veces. En este momento, todo en el objeto Usuarios es básicamente un duplicado de lo que está en AddUserViewModel(). Podría poner las anotaciones en el objeto de dominio pero no quiero hacer eso. – chobo2

Respuesta

16

¿Por qué le gustaría devolver una lista de objetos de dominio en su modelo de visualización? Eso no es lo que se supone que son los modelos de vista. Los modelos de vista deben hacer referencia solo a otros modelos de vista. Entonces tienes un buen UserViewModel que representa a un usuario. Ahora tiene que trabajar con múltiples usuarios de la vista, así que o se pasa un IEnumerable<UserViewModel> o si necesita algunas otras propiedades se diseña un modelo de vista para esto:

public class UserViewModel 
{ 
    [Required] 
    public string UserName = { get; set; } 
    [Required] 
    public string FirstName = { get; set; } 
    [Required] 
    public string LastName = { get; set; } 
} 

public class SomeViewModel 
{ 
    public List<UserViewModel> Users { get; set; } 
    public string SomeOtherProperty { get; set; } 
} 

y ahora su acción del controlador podría tener este aspecto:

public ActionResult Foo() 
{ 
    SomeModel model = _repository.GetModel(); 
    SomeViewModel viewModel = Mapper.Map<SomeModel, SomeViewModel>(model); 
    return View(viewModel); 
} 

Ahora dentro de la vista simplemente podría utilizar una plantilla de visualización para este Users propiedad (Html.DisplayFor(x => x.Users)) para mostrar una lista de ellos.


ACTUALIZACIÓN:

Después de ver su actualización aquí está la forma de proceder en términos de buenas prácticas:

public ActionResult Foo() 
{ 
    IEnumerable<Users> users = _repository.GetUsers(); 
    IEnumerable<UserViewModel> usersViewModel = Mapper 
     .Map<IEnumerable<Users>, IEnumerable<UserViewModel>>(users); 
    return View(usersViewModel); 
} 

También he utilizado un atributo AutoMap en un sample project que podría simplificar el código a esto:

[AutoMap(typeof(IEnumerable<Users>), typeof(IEnumerable<UserViewModel>))] 
public ActionResult Foo() 
{ 
    IEnumerable<Users> users = _repository.GetUsers(); 
    return View(users); 
} 

Este atributo wi Se ejecutará automáticamente después de la acción del controlador y antes de que se represente la vista, y usaría AutoMapper para reemplazar el modelo con el modelo de vista correspondiente.

+0

@Darin Dimitrov - Hmm Pensé que era malo tener una colección de modelos de vista. Es difícil determinar cuál es la manera correcta es como en este tutorial http://stephenwalther.com/blog/archive/2009/04/13/asp.net-mvc-tip-50-ndash-create-view-models .aspx está haciendo algo parecido a lo que tengo – chobo2

+0

@ chobo2, no es una mala práctica tener colecciones de modelos de vista. El ejemplo al que se refiere usa un 'IEnumerable ' que es exactamente lo que te sugerí en la primera parte de mi respuesta: 'IEnumerable '. En este ejemplo, 'Producto' debe considerarse como un modelo de vista. También debe evitar escribir bucles 'foreach' en sus vistas. Debe usar plantillas de visualización/editor. Hará tu código mucho más conciso. Por lo tanto, podría reemplazar fácilmente el foreach que se muestra en la publicación del blog con una sola línea en la vista: 'Html.DisplayFor (x => x.Products)'. –

+0

@Darin Dimitrov - ¿Pero no es su objeto de dominio? Es decir, entonces puedes considerar lo que dije a mi ViewModel (Usuario). Creo que las plantillas diplay/editor es una pregunta completamente nueva, ya que siempre uso foreach. – chobo2

Cuestiones relacionadas