2011-01-05 17 views
13

Attualmente sto cercando di capire quando utilizzare ViewModels e quando no. Sto usando Automapper per l'attività e attualmente hanno il seguente codice:ASP.NET MVC - Mappatura con Automapper

// AccountController.cs

[AuthWhereRole(Roles = AuthorizeRole.Developer)] 
public ActionResult List() 
{ 
    MembershipUserCollection users = _memberShipService.GetAllUsers(); 
    IEnumerable<ListUsersViewModel> viewModel = 
      Mapper.Map<IEnumerable<MembershipUser>, IEnumerable<ListUsersViewModel>>(users.Cast<MembershipUser>().AsEnumerable()); 

    return View("List", viewModel); 
} 

// ListUsersViewModel.cs

public class ListUsersViewModel 
{ 
    public Guid Id { get; set; } 
    public virtual string UserName { get; set; } 
    public string LastLogOn { get; set; } 
} 

// Bootstrapper.cs

public static void ConfigureAutoMapper() 
{ 
    Mapper.CreateMap<MembershipUser, ListUsersViewModel>() 
      .ForMember(x => x.UserName, o => o.MapFrom(s => s.UserName)) 
      .ForMember(x => x.Id, o => o.MapFrom(s => s.ProviderUserKey)) 
      .ForMember(x => x.LastLogOn, o => o.MapFrom(s => s.LastLoginDate)); 
} 

Mi chiedo se è una cattiva pratica mappare in questo modo solo per escludere alcune proprietà da lui modello di dominio? - E dovrei sempre usare View Models, anche se non necessario?

Grazie in anticipo.

risposta

14

In breve, si dovrebbe sempre utilizzare un ViewModel.

Utilizziamo AutoMapper sul nostro progetto e inizialmente non abbiamo fornito ViewModels separati per ogni vista. Abbiamo riscontrato problemi di prestazioni che si verificano se gli oggetti hanno riferimenti tra loro (ad esempio, l'utente ha login che hanno ruoli con utenti). AutoMapper non sapeva quando interrompere la creazione di queste raccolte.

Mentre questo non era un problema su pagine semplici, come quello nel tuo esempio, abbiamo deciso di creare un ViewModel per ogni Vista che forniva solo le proprietà necessarie a quel ViewModel. Questo ha risolto i problemi di autorizzazione e rende anche molto facile vedere le informazioni richieste da View.

Jimmy Bogard parla seguendo questo metodo in un post sul blog: http://www.lostechies.com/blogs/jimmy_bogard/archive/2009/06/29/how-we-do-mvc-view-models.aspx

+0

Questo è molto simile alle mie esperienze personali. – adamjford

9

Ecco un grande articolo su automapper e ViewModels
http://weblogs.asp.net/shijuvarghese/archive/2010/02/01/view-model-pattern-and-automapper-in-asp-net-mvc-applications.aspx

Alcuni punti chiave.

La tua domanda should I always use View Models, even when not needed?

Il commento sul post del blog dice

oggetti di dominio sono stati progettati per le esigenze di modello di dominio e si rappresenta il dominio delle nostre applicazioni. D'altra parte, visualizza gli oggetti del modello progettati per le nostre esigenze di visualizzazione.

Ed ecco come sta descrivendo usando l'automapper. Penso che l'idea di AutoMapper sia che mapperà ciò che può in base ai nomi delle proprietà.

[HttpPost] 
public ActionResult Create(ContactViewModel contactToCreate) { 

if (ModelState.IsValid) { 
    Contact newContact = new Contact(); 
    AutoMapper.Mapper.Map(contactToCreate, newContact); 
    contactRepository.CreateContact(contactToCreate.GroupId, newContact); 
} 
} 
0

Nel mio non-così-grande esperienza, la regola generale è la seguente:

  • Per le viste che mostrano il dominio Modella come è (come un record prima di premere il pulsante "modifica"), puoi semplicemente usare il tuo modello normale. Sebbene ciò non ti impedisca di creare un'altra classe che semplicemente estende il tuo modello di dominio, quindi in futuro non dovrai toccare né il controller né la vista.
  • Per il resto dei casi: ViewModels.Ecco alcuni motivi per cui
    • Se si dispone di totali (come il numero di studenti in una classe), piuttosto che calcolarli sulla vista, il ViewModel dovrebbe avere un metodo a sé stante.
    • Impaginazione. Di solito quando si visualizzano molti record, si ha: AllRecords o alcune quantità di stack di impaginazione (20, 50, 100, ad es.). Il modello di dominio deve solo servire business logic in generale (e vi impedisce di aggiungere che il numero di telefono è "Fish", per esempio), ma il ViewModel è interessato mantenendo uno stato della vista

Quindi immagino, sì, tipo di sempre

Problemi correlati