ASP.NET MVC - jak dokładnie używać modeli widoku

Załóżmy, że mam stronę, która pozwala na edycję danych użytkownika, więc mam taki ViewModel:

public class UserViewModel {
    public string Username { get; set; }
    public string Password { get; set; }
    public int ManagerId { get; set; }
    public string Category { get; set; }
}

Więc na mojej akcji EditUser mogę to przekazać z powrotem przez segregator modelu, a następnie mogę mapować to do modelu domeny:

public ActionResult EditUser(UserViewModel user) {
    ...

Jednak strona, która wyświetla formularz, potrzebuje również szczegółów, takich jak lista menedżerów i kategorii, aby zapewnić listę rozwijaną dla tych pól. Może również wyświetlać listę innych użytkowników na pasku bocznym, dzięki czemu można przełączać się między różnych użytkowników, których edytujesz.

Więc mam inny model widoku:

public class ViewUserViewModel {
    public UserViewModel EditingUser { get; set; }
    public IEnumerable<SelectListItem> Managers { get; set; }
    public IEnumerable<SelectListItem> Categories { get; set; }
    public IEnumerable<SelectListItem> AllUsers { get; set; }
}
Czy to jest właściwy sposób? Czy obie są modelami widokowymi? Jeśli tak, czy istnieje konwencja nazewnictwa, której powinienem używać, aby odróżnić maszyny wirtualne, które są jak modele, od maszyn wirtualnych, które zawierają tylko dane dla strony? Czy źle to zrozumiałem?
Author: littlecharva, 2013-05-14

3 answers

Jak to zrobić w skrócie:

  1. Utwórz osobną klasę ViewModel dla każdego formularza na stronie, a następnie wyrenderuję te klasy z PartialViews jako @{Html.RenderPartial("PartialName", Model.PartialModel);}.
  2. jeśli strona zawiera takie rzeczy jak Meta html, robię oddzielną klasę dla Meta i umieszczam ją w sekcji na stronie.
  3. Przypadki odpoczynku, takie jak "Czy powinienem umieścić to w oddzielnej klasie?"to twój osąd.

Więc na przykład masz stronę, która ma jakiś Pasek logowania/rejestracji lub popup nieważne.

public class SomePageViewModel
{
    public RegisterBarVM Register { get; set; }
    public LoginBarVM LoginBar { get; set; }

    public MetasVM Metas { get; set; }
    public string MaybePageTitle { get; set;}
    public string MaybePageContent { get; set;}

    [HiddenInput(DisplayValue = false)]
    public int IdIfNeeded { get; set; }

    public IEnumerable<SelectListItem> SomeItems {get; set;}
    public string PickedItemId { get;set; }
}

public class RegisterBarVM
{
    public string RegisterUsername {get;set;}
    public string RegisterPassword {get;set;}
    //...
}

public class LoginBarVM
{
    public string LoginUserame {get;set;}
    public string LoginPassword {get;set;}
    //...
}

//cshtml
@model yourClassesNamespace.SomePageViewModel
@{
    Html.RenderPartial("LoginBar", Model.LoginBar); //form inside
    Html.RenderPartial("RegisterBar", Model.RegisterBar); //form inside

    using(Html.BeginForm())
    {
        @Html.EditorFor(m => m.IdIfNeeded)
        @Hmtl.EditorFor(m => m.MaybePageTitle)
        @Hmtl.EditorFor(m => m.MaybePageContent)

        @Hmtl.DropDownListFor(m => m.PickedItemId, new SelectList(Model.SomeItems))

        <input type="submit" value="Update" />
    }
}

@section Metas {
    @{Html.RenderPartial("Meatas", Model.Metas}
}

O szablonach edytora Brad Wilsons Blog i po prostu google lub szukać zasobów stosy o szablonach wyświetlania / edytora i HtmlHelpers. Wszystkie one są bardzo przydatne do budowania spójnych stron internetowych.

 20
Author: Mariusz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-05-14 21:20:57

"Model widoku" to tylko wzór. Nie ma nic magicznego w nazwie, ale generalnie każda klasa przekazywana do widoku (czy to po prostu do wyświetlania danych, czy do celów przesyłania formularzy) jest określana jako "model widoku" i otrzymuje nazwę taką jak FooViewModel lub FooVM, aby wskazać, że jest częścią tego wzorca "modelu widoku".

Nie chcę być zbyt filozoficzny na ciebie, ale myślę, że trochę odniesienia do wzorców w grze będzie pomocne. ASP.NET MVC oczywiście wystarczy zachęca model architektoniczny MVC (Model-View-Controller). W MVC model jest kontenerem dla wszystkich aplikacji logiki biznesowej . Kontroler jest odpowiedzialny za obsługę żądania, pobranie modelu, renderowanie widoku z tym modelem i zwrócenie odpowiedzi. Wydaje się to dużą odpowiedzialnością, ale w rzeczywistości framework zajmuje się większością tego za kulisami, więc kontrolery są zazwyczaj (i powinny być) bardzo lekkie w kodzie. Są odpowiedzialni za nagie minimalna ilość funkcjonalności do podłączenia wszystkiego. Wreszcie, widok jest odpowiedzialny za tworzenie warstwy interfejsu użytkownika, która pozwala użytkownikowi na interakcję z danymi w modelu. Nie jest to odpowiedzialne za same dane, ani nie powinno być (ViewData/ViewBag jest tu dość dużym naruszeniem, przynajmniej w takim stopniu, w jakim kończy się to używaniem przez programistów w praktyce).

Oznacza to, że większość logiki aplikacji powinna być w twoim modelu, i zazwyczaj jest to dobra rzecz. Ponieważ jednak model jest przystanią danych aplikacji, zazwyczaj zostaje utrzymany w bazie danych lub podobnej. Stwarza to pewien konflikt interesów, ponieważ teraz musisz rozpocząć balansowanie między tym, jakie dane powinny być przechowywane, a jakie dane powinny istnieć tylko w celu wyświetlania.

Tutaj pojawiają się modele widoku. MVVM (Model-View-View Model), nieco równoległy do wzorca MVC, rozpoznaje nieodłączne problemy w podejściu opartym na jednym modelu, aby rządzić nimi wszystkimi. Nie wejdę w wiele szczegóły tutaj, ponieważ MVC nie używa tego wzoru. Jednak większość ASP.NET Programiści MVC wybrali model widoku MVVM. To, co zasadniczo kończy się, to wspierana bazą danych Jednostka (tradycyjny model), a następnie zazwyczaj wiele różnych modeli widoków, które reprezentują tę jednostkę w różnych stanach. Dzięki temu model może zawierać logikę biznesową, która jest istotna dla trwałości, podczas gdy modele widoku zawierają logikę biznesową, która jest istotna dla wyświetlania, tworzenia i aktualizowania model.

Trochę zboczyłem z drogi, ale krótko i na dłuższą metę to, że to, co robisz, jest całkowicie akceptowalne. To dobra praktyka. Twórz tyle modeli widoków, ile wymaga aplikacja, i używaj ich do rzeczywistego przechowywania danych i logiki biznesowej niezbędnych dla widoków. Ani twój kontroler, ani widok nie powinny wiedzieć, jak utworzyć SelectList dla rozwijanego menu.)
 94
Author: Chris Pratt,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-05-14 18:28:10

Osobiście wolę umieścić wszystkie informacje wymagane do renderowania strony w ViewModel, ponieważ jest to cel ViewModel-aby dostarczyć wszystkie dane do widoku. Więc mój UserViewModel zawiera właściwości dla Managers, Categories i AllUsers i kontroler wypełniłby te zbiory przed przekazaniem ViewModel do widoku.

To jest zasadniczo to, co zrobiłeś - po prostu usuwa dodatkowy model widoku z równania.

Widziałem też inne programiści używają ViewData do wysyłania list rozwijanych do widoku, ale nie podoba mi się to, ponieważ ViewData nie jest mocno wpisywana, podczas gdy ViewModel jest.

 9
Author: Jason Berkan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-05-14 16:38:11