Хорошо ли определять свойства типа модели во ViewModel, ASP.net MVC

Я прочитал пару сообщений об использовании ViewModel в ASP.net MVC и понял, что он отличается от ViewModel в шаблоне M-V-VM.

ViewModel используется, чтобы избежать прямого доступа к модели из View, но хорошо ли иметь свойства типа (определенные на уровне модели) в ViewModel? Это означает, что в конечном итоге нам нужно включить пространство имен модели в ViewModel.

E.g.

Модель
1. Сущность YesNoTBDValue / класс POCO

public partial class YesNoTBDValue
{
    public int Id { get; set; }
    public string Name { get; set; }
}

2 Класс YesNoTBDValue, используемый в сущности Project (определен в самой модели)

public partial class Project
{
     public virtual YesNoTBDValue IsAvailable { get; set; }
}

Просмотр модели
1. ProjectEditViewModel

public class ProjectEditViewModel
{
HERE TO INCLUDE YesNoTBDValue CLASS, I NEED TO INCLUDE MODELS 
OR THERE IS BETTER WAY?
    public List<YesNoTBDValue> YesNoTBDValues { get; set; }
    public int IsAvailableSelectedItemId { get; set; }
}

Контроллер
Контроллер проекта (в действии редактирования, создающем новый экземпляр модели представления)

ProjectEditViewModel projectEditViewModel = new ProjectEditViewModel
{
    YesNoTBDValues = db.YesNoTBDValues.ToList()
};

Просмотр
Отображение DropDownList из списка YesNoTBDValues ​​и сохранение выбранного элемента в IsAvailableSelectedItemId

@Html.DropDownList("IsAvailableSelectedItemId ", 
new SelectList(Model.YesNoTBDValues, "Id", "Name",
            Model.IsAvailableSelectedItemId ))

Пожалуйста, посоветуйте мне, как это должно быть правильно закодировано.

Повторяющийся вопрос: должна ли ViewModel включать пространство имен модели? В моем примере YesNoTBDValue определено в модели, и для его использования я использую пространство имен модели.

/ ДРУГОЙ ПОДХОД /

Не удовлетворенный своим существующим подходом, я загрузил исходный код Microsoft Nuget Gallery с github и понял, что они никогда не использовали МОДЕЛИ внутри VIEWMODEL, что для меня имеет смысл. Я немного изменил приведенный выше код (, чтобы удалить ссылку на модель из ViewModel) и обнаружил, что он отлично работает.

Вот мои изменения:

Модель Без изменений, как есть

Просмотр модели
1. Создайте копию класса YesNoTBDValue, скажите YesNoTBDValueViewModel.

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

2 Используйте эту модель просмотра в ProjectEditViewModel и удалите ссылку на модель.

public class ProjectEditViewModel
{
     public List<YesNoTBDValueViewModel> YesNoTBDValues {get;set;}
     public int IsAvailableSelectedItem {get;set;}
}

Контроллер Измените способ заполнения этих значений. (В действии редактирования)

ProjectEditViewModel projectEditViewModel = new ProjectEditViewModel
{
    YesNoTBDValues = db.YesNoTBDValues.Select(
                x => new LMSPriorTool.ViewModels.YesNoTBDValueVM
 {
    Id = x.Id,
    Name = x.Name
 }).ToList()
}

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

Пожалуйста, пролейте свет, если мне что-то здесь не хватает.


person Rohit    schedule 29.06.2013    source источник
comment
Почему не использовать MVC? MVVM является производным от PM, предназначенного для приложений с богатым пользовательским интерфейсом. Я не уверен, что MVVM также подходит для ASP.net.   -  person Bill Zhang    schedule 30.06.2013
comment
@BillZhang: Здесь я не имею в виду шаблон MVVM. Фактически, модель представления в ASP.net MVC4 отличается от модели представления в шаблоне MVVM. Было много споров о необходимости ViewModel в ASP.net MVC4 (в самом StackOverflow), и в целом (в этих дебатах) предпочтительнее иметь ViewModel. Что ты думаешь?   -  person Rohit    schedule 30.06.2013
comment
ViewModel - это специальная модель для просмотра. В шаблоне WPF и PM View и Presenter взаимодействуют через DataBinding и Commanding, поэтому Presenter превращается в объект, более похожий на модель, так называемую ViewModel. Я не знаком с ASP.Net/MVC, если в вашем случае Модель не может удовлетворить потребности View, например, требуются сложные преобразователи данных, вы можете добавить слой, подобный ViewModel, чтобы сделать модель более дружественной к пользовательскому интерфейсу. Думаю, это вполне разумно.   -  person Bill Zhang    schedule 30.06.2013
comment
Даже у меня был такой же опыт. В прошлом я работал с приложением WPF и использовал шаблон MVVM. Но между двумя есть разница. Вы правы насчет MVVM в WPF.   -  person Rohit    schedule 30.06.2013


Ответы (1)


Я стараюсь, чтобы ViewModel содержал только простые типы, которые естественны в контексте представления. Таким образом, я минимизирую логику рендеринга в представлении и сохраняю его чистым.

Вашу ViewModel можно очень просто представить примерно так:

public class ProjectEditViewModel
{
    public int YesNoTBDValueSelected { get; set; }
    public SelectList YesNoTBDValueOptions { get; set; }
}

or

public class ProjectEditViewModel
{
    public int YesNoTBDValueSelected { get; set; }
    public IEnumerable<SelectListItem> YesNoTBDValueOptions { get; set; }
}

Теперь логика для генерации SelectList входит в ваше Project ‹-> ProjectEditViewModel отображение и не используется View.

person fearofawhackplanet    schedule 30.06.2013
comment
Даже я реализовал этот способ только в первый раз, но я был пойман в том, как передать выбранный раскрывающийся элемент в действие сообщения контроллера. Теперь все настроено, не потребовалось много времени, чтобы изменить все для использования SelectList. (Все еще не смог использовать IEnumerable ‹SelectListItem›, он выдает ошибку, например, SelectListItem не содержит свойства с именем 'id'). Скоро загрузим сюда код - person Rohit; 30.06.2013
comment
Удивлен, увидев, что мое изменение не было одобрено. Я добавил полный код для реализации этого подхода. Это определенно было полезно для некоторых. - person Rohit; 01.07.2013
comment
@RohitKandhal, вы можете добавить свой новый код в качестве другого ответа, я уверен, что это кому-то поможет. - person fearofawhackplanet; 01.07.2013