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

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

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

Например

модель
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 включать пространство имен Model? В моем примере YesNoTBDValue определено в Model, и для его использования я использую пространство имен Model.

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

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

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

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

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

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

2 Используйте эту ViewModel в 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 полностью отделены друг от друга. Оставить этот вопрос открытым для дальнейшего обсуждения.

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

1 ответ

Решение

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

Ваш ViewModel может быть очень просто представлен чем-то вроде:

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

или же

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

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

Другие вопросы по тегам