MVC и Entity Framework Html.DisplayNameFor с составной ViewModel
Мне вполне комфортно с MVVM, использующей WPF / Silverlight, но это моя первая попытка создать веб-приложение MVC… просто к сведению.
Я создал контроллер TestSitesController, который был автоматически сгенерирован из класса модели «Сайт» в моей модели Entity Framework (шаблон, который генерирует действия и представления для чтения / записи). Единственное, что я изменил, это то, что в трех местах был параметр по умолчанию Guid id = null для некоторых методов. Я только что избавился от «= ноль», все отлично работает. Вот пример того, что я изменил
public ActionResult Delete(Guid id = null)
{
//....
}
Это было изменено на
public ActionResult Delete(Guid id)
{
//....
}
Модель сайта - это не что иное, как SiteId, Abbreviation и DisplayName ... пытаясь сделать его максимально простым для этого вопроса. Итак, я запускаю сайт и захожу в htpp: //.../TestSites/ и все работает отлично.
Я заметил, что все мои представления (Create, Delete, Details и Edit) используют @model MVCWeb.MyEntities.Site, с которым у меня сейчас все в порядке; но в представлении Index.cshtml я заметил, что он использует
@model IEnumerable<MVCWeb.MyEntities.Site>
Это прекрасно работает для сгенерированного шаблона, но я хотел бы использовать «модель составного представления», и, возможно, именно здесь я пытаюсь смешать свои знания MVVM, но буду придерживаться этого, если это возможно. На мой взгляд, модель составного представления - это просто модель, специфичная для представления, состоящего из 1 или более моделей сущностей, а также дополнительных свойств, таких как SelectedSiteId и т. Д.
Поэтому я создал очень простую ViewModel под названием TestSitesViewModel
public class TestSitesViewModel
{
//Eventually this will be added to a base ViewModel to get rid
//of the ViewBag dependencies
[Display(Name = "Web Page Title")]
public string WebPageTitle;
public IEnumerable<MVCWeb.MyEntities.Site> Sites;
//Other Entities, IEnumberables, or properties go here
//Not important for this example
}
Затем в моем контроллере я добавил метод действия под названием IndexWithViewModel
public ActionResult IndexWithViewModel()
{
var vm = new TestSitesViewModel();
vm.WebPageTitle = "Sites With Composite View Model";
vm.Sites = db.Sites.ToList();
return View(vm);
}
Затем я сделал копию Index.cshtml и назвал ее IndexWithModel.cshtml в соответствии с моим новым именем метода ActionResult. Я изменил верхнюю строчку
@model IEnumerable<MVCWeb.MyEntities.Site>
к
@model MVCWeb.Models.TestSitesViewModel
Я добавил это перед разделом таблицы, чтобы проверить DisplayNameFor и DisplayFor
@Html.DisplayNameFor(model => model.WebPageTitle)
@Html.DisplayFor(model => model.WebPageTitle)
<br />
Изменил
@foreach (var item in Model) {
к
@foreach (var item in Model.Sites) {
И закомментировал раздел tr, который на данный момент содержит все заголовки таблиц. Все работает отлично, за исключением того, что @ Html.DisplayNameFor отображает имя переменной «WebPageTitle» вместо использования «Заголовка веб-страницы», как указано в атрибуте «Отображение» аннотации данных в
[Display(Name = "Web Page Title")]
public string WebPageTitle;
Также, если я прокомментирую обратно в разделе tr, который содержит информацию заголовка таблицы. Я не могу на всю жизнь выяснить, что положить в испытанную модель. Сайты. Аббревиатура, модель. Сайты [0]. Аббревиатура и другие различные комбинации, но получаю ошибки.
<tr>
<th>
@Html.DisplayNameFor(model => model.Abbreviation)
</th>
<th>
@Html.DisplayNameFor(model => model.DisplayName)
</th>
<th></th>
</tr>
Так что я должен использовать там? Я не совсем уверен, почему model.Sites.Abbreviation не работает, так как Sites - это тот же тип, который использовался в качестве модели в оригинальном Index.cshtml.