MVC i Entity Framework Html.DisplayNameFor z Composite ViewModel

Jestem całkiem zadowolony z MVVM przy użyciu WPF / Silverlight, ale jest to moja pierwsza próba aplikacji sieciowej MVC… tylko fyi dla mojego tła.

Stworzyłem kontroler o nazwie TestSitesController, który został automatycznie wygenerowany z klasy modelu „Site” w moim modelu Entity Framework Model (szablon generujący akcje i widoki odczytu / zapisu). Jedyną rzeczą, którą zmodyfikowałem, było 3 miejsca, dla niektórych metod był domyślny parametr Guid id = null. Właśnie pozbyłem się „= null”, wszystko działa poprawnie. Oto przykład tego, co zmieniłem

public ActionResult Delete(Guid id = null)
{
    //....
}

To zostało zmienione na

public ActionResult Delete(Guid id)
{
    //....
}

Model witryny nie jest niczym szczególnym SiteId, skrótem i DisplayName… starając się, aby to pytanie było jak najprostsze. Ok, więc uruchamiam stronę i htpp: //.../TestSites/ i wszystko działa idealnie.

Zauważyłem, że wszystkie moje widoki (Create, Delete, Details i Edit) używają @model MVCWeb.MyEntities.Site, z którym teraz jestem w pełni zadowolony; ale w widoku Index.cshtml zauważyłem, że używa

@model IEnumerable<MVCWeb.MyEntities.Site>

Działa to dobrze dla wygenerowanego szablonu, ale chciałbym użyć „Composite View Model” i być może właśnie tam próbuję połączyć moją wiedzę o MVVM, ale pozostanę przy tym, jeśli to możliwe. Moim zdaniem model widoku złożonego jest tylko modelem specyficznym dla widoku, który składa się z 1 lub więcej modeli jednostek wraz z dodatkowymi właściwościami, takimi jak SelectedSiteId itp.

Dlatego stworzyłem bardzo prosty ViewModel o nazwie 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
}

Następnie w moim kontrolerze dodałem metodę akcji o nazwie IndexWithViewModel

public ActionResult IndexWithViewModel()
{
    var vm = new TestSitesViewModel();
    vm.WebPageTitle = "Sites With Composite View Model";
    vm.Sites = db.Sites.ToList();

    return View(vm);
}

Następnie zrobiłem kopię Index.cshtml i nazwałem ją IndexWithModel.cshtml, aby pasowała do mojej nowej nazwy metody ActionResult. Zmieniłem górną linię

@model IEnumerable<MVCWeb.MyEntities.Site>

Do

@model MVCWeb.Models.TestSitesViewModel

Dodałem to przed sekcją tabeli, aby przetestować DisplayNameFor i DisplayFor

@Html.DisplayNameFor(model => model.WebPageTitle)
&nbsp;
@Html.DisplayFor(model => model.WebPageTitle)
<br />

Zmieniłem

@foreach (var item in Model) {

Do

@foreach (var item in Model.Sites) {

I skomentował sekcję tr, która na razie zawiera wszystkie nagłówki tabeli. Wszystko działa doskonale, z wyjątkiem tego, że @ Html.DisplayNameFor wyświetla nazwę zmiennej „WebPageTitle” zamiast „Tytuł strony sieci Web”, jak wskazano w atrybucie Wyświetlanie adnotacji danych w

[Display(Name = "Web Page Title")]
public string WebPageTitle;

Również jeśli komentuję z powrotem w sekcji tr zawierającej informacje nagłówka tabeli. Nie mogę przez całe życie dowiedzieć się, co włożyć Próbowałem modelu.Sites.Abbreviation, model.Sites [0]. Skrót i różne inne kombinacje, ale pojawiają się błędy.

<tr>
    <th>
        @Html.DisplayNameFor(model => model.Abbreviation)
    </th>
    <th>
        @Html.DisplayNameFor(model => model.DisplayName)
    </th>
    <th></th>
</tr>

Co więc powinienem tam wykorzystać? Nie jestem pewien, dlaczego model.Sites.Abbreviation nie działa, ponieważ Sites to dokładnie ten sam typ, który był używany jako model w oryginalnym Index.cshtml

questionAnswers(2)

yourAnswerToTheQuestion