ASP.NET MVC - отображение с помощью Automapper

В настоящее время я пытаюсь выяснить, когда использовать ViewModels, а когда нет. Я использую 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));
}

Мне интересно, может ли его плохая практика сопоставлять это, чтобы исключить некоторые свойства из модели домена? - И должен ли я всегда использовать модели просмотра, даже если это не нужно?

Спасибо заранее.

Ответы

Ответ 1

Короче говоря, да, вы всегда должны использовать ViewModel.

Мы используем AutoMapper для нашего проекта, и изначально мы не предоставляли отдельные ViewModels для каждого представления. Мы обнаружили, что у нас были некоторые проблемы с производительностью, которые возникли, если объекты имеют ссылки друг на друга (т.е. У пользователя есть логины, у которых есть роли, у которых есть пользователи). AutoMapper не знал, когда прекратить сбор этих коллекций.

Хотя это не было проблемой на простых страницах, например, в вашем примере, мы решили создать ViewModel для каждого представления, предоставляя только свойства, необходимые этому ViewModel. Это разрешило проблемы с разрешениями, а также очень легко увидеть информацию, которую требует просмотр.

Джимми Богард рассказывает о следующем методе в блоге: http://www.lostechies.com/blogs/jimmy_bogard/archive/2009/06/29/how-we-do-mvc-view-models.aspx

Ответ 2

Вот отличная статья об AutoMapper и ViewModels
http://weblogs.asp.net/shijuvarghese/archive/2010/02/01/view-model-pattern-and-automapper-in-asp-net-mvc-applications.aspx

Некоторые ключевые моменты.

Ваш вопрос should I always use View Models, even when not needed?

Комментарий к сообщению в блоге гласит:

Объекты домена предназначены для нужд модели домена и представляют собой домен наших приложений. С другой стороны, объекты View Model, предназначенные для наших потребностей для представлений.

И вот как он описывает использование automapper. Я думаю, что идея AutoMapper заключается в том, что она будет отображать то, что она может, на основе названий свойств.

[HttpPost]
public ActionResult Create(ContactViewModel contactToCreate) {

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

Ответ 3

В моем не столь обширном опыте эмпирическое правило выглядит следующим образом:

  • Для представлений, отображающих модель домена, как есть (как и запись, прежде чем вы нажмете кнопку "Изменить" ), вы можете просто использовать свою обычную модель. Хотя это не мешает вам создать еще один класс, который просто расширяет вашу модель домена, поэтому в будущем вам не нужно касаться как контроллера, так и представления.
  • Для остальных случаев: ViewModels. Вот несколько причин, почему
    • Если у вас есть итоговые значения (например, количество учеников в классе), а не вычисление того, что в представлении, ViewModel должен иметь собственный метод.
    • Разбивка. Обычно при отображении многих записей вы имеете либо: AllRecords, либо некоторое количество папок для разбивки на страницы (20, 50, 100, например). Модель домена должна просто обслуживать бизнес-логику в целом (и не позволять вам добавить, что ваш номер телефона - "Рыба", например), но viewmodel относится к сохранению состояния представления

Итак, я думаю, да, вроде всегда