Хорошо ли определять свойства типа "Модель" во 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
,