Подтвердить что ты не робот

Шаблон ASP.NET MVC ViewModel

EDIT: Я сделал что-то намного лучше заполнить и прочитать данные из представления с помощью ViewModels, назвав его ValueInjecter. http://valueinjecter.codeplex.com/

используется http://prodinner.codeplex.com - пример приложения ASP.net MVC  

вы можете увидеть лучший способ использования ViewModels в prodinner

использование ViewModel для хранения логики отображения не было такой хорошей идеей, потому что было повторение и нарушение SRP, но теперь с ValueInjecter у меня есть чистые ViewModels и сухой код отображения


Что старый материал, не используйте его:
Я создал шаблон ViewModel для редактирования материалов в asp.net mvc этот шаблон полезен, когда вам нужно создать форму для редактирования объекта, и вам нужно наложить на форму раскрывающееся меню, чтобы пользователь мог выбрать некоторые значения
    public class OrganisationBadViewModel
    {
        //paramterless constructor required, cuz we are gonna get an OrganisationViewModel object from the form in the post save method
        public OrganisationViewModel() : this(new Organisation()) {}
        public OrganisationViewModel(Organisation o)
        {
            Organisation = o;
            Country = new SelectList(LookupFacade.Country.GetAll(), "ID", "Description", CountryKey);  
        }       
        //that the Type for whom i create the viewmodel
        public Organisation Organisation { get; set; }
...     

    }
4b9b3361

Ответ 1

Есть несколько вещей, которые меня беспокоят.

  • Терминология. ViewModel - это простой вид данных, который заполняется и затем потребляется контроллером. Просмотр ничего не знает о контроллере, поскольку инфраструктура ASP.NET MVC отвечает за выбор контроллеров и соответствующих действий. Контроллер обрабатывает взаимодействие пользователя. Я думаю, что это больше похоже на пассивный вид, чем на ViewModel (я полагаю, что ViewModel подразумевает модель Model-View-ViewModel).

  • Подробности. Контроллер, который заполняет данные просмотра, не должен знать подробные сведения о том, как выглядит представление. Однако OrganisationViewModel.Country раскрывает ненужные данные (SelectListItem - это подробное описание реализации). Таким образом, управление контроллером зависит от деталей реализации представления. Я думаю, это нужно изменить, чтобы избежать этого. Подумайте об использовании какого-либо объекта, который будет хранить данные для страны.

Надеюсь, что это поможет.

Ответ 2

Это очень похоже на рекомендованную практику в Wrox Professional ASP.NET MVC, первая глава которой доступна бесплатно указанный выше URL.

Начиная со страницы 100, они имеют раздел в ViewData и ViewModels.

Когда класс Controller решает вернуть HTML-ответ клиенту, он отвечает за явно передачу шаблону представления всех данных, необходимых для отображения ответа. Просмотр шаблонов никогда не должен выполнять какой-либо поиск данных или логику приложения - и вместо этого должен ограничивать себя только кодом рендеринга, который отключен от модели/данных, переданных ему контроллером.

[...]

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

Взято из "Главы 1" Nerd Dinner "из Профессионального ASP.NET MVC 1.0, написанного Робом Коннери и др., опубликованным Wrox". Оригинал доступен по адресу http://tinyurl.com/aspnetmvc

Ответ 3

В общем, я думаю, что он выглядит хорошо, и обычно это хорошая идея для создания viewmodels для ваших объектов домена.

Я не рассматривал каждую строку кода, но одна вещь, которая привлекла мое внимание, была конструкторами OrganisationViewModel. Я бы переписал его, используя:

public OrganisationViewModel() : this(new Organisation()) { }

public OrganisationViewModel(Organisation o)
{
  Organisation = o;
  InitCollections();
}

Это удаляет дубликат кода, так как вам не нужно вызывать InitCollections() в обоих конструкторах. Конечно, это лишь незначительная деталь и не имеет ничего общего с общей идеей.

Ответ 4

Мы начали это делать, но наши контроллеры начали становиться чудовищными (поскольку наши ViewModels не обязательно отображались в нашей базе данных 1:1). Чтобы облегчить это, мы создали классы Mapper, которые создают ViewModel, а затем вернутся к привязке данных к базе данных. Затем контроллер просто вызывает методы класса Mapper. Кажется, хорошо работает.