Jestem nowy w ASP.NET MVC. Mam problem ze zrozumieniem celu ViewModel.
Co to jest ViewModel i dlaczego potrzebujemy ViewModel dla aplikacji ASP.NET MVC?
Jeśli otrzymam dobry przykład jego działania i wyjaśnienia, byłoby lepiej.
asp.net-mvc
viewmodel
wyjątkowy
źródło
źródło
Odpowiedzi:
A
view model
reprezentuje dane, które chcesz wyświetlić na widoku / stronie, niezależnie od tego, czy są one używane w przypadku tekstu statycznego, czy wartości wejściowych (takich jak pola tekstowe i listy rozwijane), które można dodać do bazy danych (lub edytować). To jest coś innego niż twojedomain model
. Jest to model widoku.Powiedzmy, że masz
Employee
klasę reprezentującą model Twojej domeny pracowniczej i zawiera ona następujące właściwości (niepowtarzalny identyfikator, imię, nazwisko i data utworzenia):Modele widoku różnią się od modeli domen tym, że modele widoku zawierają tylko dane (reprezentowane przez właściwości), których chcesz użyć w swoim widoku. Załóżmy na przykład, że chcesz dodać nowy rekord pracownika, model widoku może wyglądać następująco:
Jak widać, zawiera tylko dwie właściwości. Te dwie właściwości znajdują się również w modelu domeny pracowniczej. Dlaczego możesz o to zapytać?
Id
może nie być ustawiony z widoku, może być automatycznie generowany przez tabelę pracownika. IDateCreated
może być również ustawiony w procedurze przechowywanej lub w warstwie serwisowej aplikacji. TakId
iDateCreated
nie są potrzebne w modelu widoku. Możesz wyświetlić te dwie właściwości, gdy przeglądasz dane pracownika (pracownika, który został już przechwycony) jako tekst statyczny.Podczas ładowania widoku / strony metoda tworzenia akcji w kontrolerze pracowniczym utworzy instancję tego modelu widoku, w razie potrzeby zapełni wszelkie pola, a następnie przekaże ten model widoku do widoku / strony:
Twój widok / strona może wyglądać tak (zakładając, że używasz
ASP.NET MVC
iRazor
silnik wyświetlania):Walidacja zostałaby zatem dokonana tylko w dniu
FirstName
iLastName
. Korzystanie z FluentValidation możesz mieć sprawdzanie poprawności w następujący sposób:A w przypadku adnotacji danych może to wyglądać tak:
Najważniejszą rzeczą do zapamiętania jest to, że model widoku reprezentuje tylko dane, których chcesz użyć , nic więcej. Możesz sobie wyobrazić niepotrzebny kod i sprawdzanie poprawności, jeśli masz model domeny z 30 właściwościami i chcesz zaktualizować tylko jedną wartość. Biorąc pod uwagę ten scenariusz, miałbyś tylko tę jedną wartość / właściwość w modelu widoku, a nie wszystkie właściwości, które są w obiekcie domeny.
Model widoku może zawierać nie tylko dane z jednej tabeli bazy danych. Może łączyć dane z innej tabeli. Weź mój przykład powyżej dotyczący dodawania nowego rekordu pracownika. Oprócz dodania tylko imienia i nazwiska możesz również dodać dział pracownika. Ta lista działów będzie pochodzić z twojego
Departments
stołu. Teraz masz dane z tabelEmployees
iDepartments
w jednym modelu widoku. Musisz wtedy dodać następujące dwie właściwości do modelu widoku i zapełnić go danymi:Podczas edycji danych pracownika (pracownika, który został już dodany do bazy danych) nie różni się on znacznie od mojego powyższego przykładu. Utwórz model widoku, nazwij go na przykład
EditEmployeeViewModel
. Posiadaj tylko dane, które chcesz edytować w tym modelu widoku, takie jak imię i nazwisko. Edytuj dane i kliknij przycisk Prześlij. Nie martwiłbym się zbytnio o toId
pole, ponieważId
wartość prawdopodobnie będzie w adresie URL, na przykład:Weź to
Id
i przekaż je do warstwy repozytorium wraz z wartościami imienia i nazwiska.Podczas usuwania rekordu zwykle podążam tą samą ścieżką, co w przypadku modelu widoku edycji. Miałbym również adres URL, na przykład:
Kiedy widok ładuje się po raz pierwszy, pobierałem dane pracownika z bazy danych przy użyciu
Id
3. Korzystając z tego, wyświetlałem tekst statyczny na moim widoku / stronie, aby użytkownik mógł zobaczyć, który pracownik jest usuwany. Gdy użytkownik kliknie przycisk Usuń, po prostu użyjęId
wartości 3 i przekażę ją do mojej warstwy repozytorium. Potrzebujesz tylkoId
usunąć rekord z tabeli.Inna kwestia: naprawdę nie potrzebujesz modelu widoku dla każdej akcji. Jeśli są to proste dane, dobrze byłoby użyć tylko
EmployeeViewModel
. Jeśli jest to skomplikowana liczba wyświetleń / stron i różnią się one od siebie, sugeruję użycie osobnych modeli widoków dla każdego z nich.Mam nadzieję, że rozwiąże to wszelkie nieporozumienia dotyczące modeli wyświetlania i modeli domen.
źródło
Model widoku to klasa reprezentująca model danych używany w określonym widoku. Możemy użyć tej klasy jako modelu strony logowania:
Za pomocą tego modelu widoku można zdefiniować widok (silnik widoku Razor):
I działania:
Który daje ten wynik (ekran jest robiony po przesłaniu formularza, z komunikatami walidacyjnymi):
Jak widać, model widoku ma wiele ról:
LabelFor
,EditorFor
,DisplayFor
pomocników).Kolejny przykład modelu widoku i jego pobierania: Chcemy wyświetlać podstawowe dane użytkownika, jego uprawnienia i nazwę użytkownika. Tworzymy specjalny model widoku, który zawiera tylko wymagane pola. Pobieramy dane z różnych jednostek z bazy danych, ale widok jest świadomy tylko klasy modelu widoku:
Wyszukiwanie:
źródło
Edycja: Zaktualizowałem tę odpowiedź na moim blogu:
http://www.samwheat.com/post/The-function-of-ViewModels-in-MVC-web-development
Moja odpowiedź jest nieco długa, ale uważam, że ważne jest porównanie modeli widoków z innymi typami często używanych modeli, aby zrozumieć, dlaczego są one różne i dlaczego są konieczne.
Podsumowując i bezpośrednio odpowiadając na zadane pytanie:
Mówiąc ogólnie, model widoku jest obiektem, który zawiera wszystkie właściwości i metody niezbędne do renderowania widoku. Wyświetl właściwości modelu są często powiązane z obiektami danych, takimi jak klienci i zamówienia, a ponadto zawierają również właściwości związane ze stroną lub samą aplikacją, takie jak nazwa użytkownika, nazwa aplikacji itp. Wyświetl modele zapewniają wygodny obiekt, który można przekazać do silnika renderującego utwórz stronę HTML. Jednym z wielu powodów korzystania z modelu widoku jest to, że modele widoku zapewniają sposób testowania jednostkowego niektórych zadań prezentacji, takich jak obsługa danych wejściowych użytkownika, sprawdzanie poprawności danych, pobieranie danych do wyświetlenia itp.
Oto porównanie modeli jednostek (np. Modeli DTO, np. Modeli), modeli prezentacji i modeli widoków.
Obiekty przesyłania danych znane również jako „Model”
Obiekt przenoszenia danych (DTO) to klasa o właściwościach pasujących do schematu tabeli w bazie danych. DTO są nazwane ze względu na ich powszechne użycie do przesyłania danych do iz magazynu danych.
Charakterystyka DTO:
• Są obiektami biznesowymi - ich definicja zależy od danych aplikacji.
• Zwykle zawierają tylko właściwości - bez kodu.
• Używany głównie do transportu danych do iz bazy danych.
• Właściwości dokładnie lub ściśle pasują do pól w określonej tabeli w magazynie danych.
Tabele bazy danych są zwykle znormalizowane, dlatego DTO są zwykle znormalizowane. To sprawia, że mają ograniczone zastosowanie do prezentacji danych. Jednak w przypadku niektórych prostych struktur danych często mają się całkiem dobrze.
Oto dwa przykłady tego, jak mogą wyglądać DTO:
Modele prezentacji
Model prezentacji to narzędzie klasą używaną do renderowania danych na ekranie lub w raporcie. Modele prezentacji są zwykle używane do modelowania złożonych struktur danych, które składają się z danych z wielu DTO. Modele prezentacji często przedstawiają zdenormalizowany widok danych.
Charakterystyka modeli prezentacji:
• Są obiektami biznesowymi - ich definicja zależy od danych aplikacji.
• Zawierają głównie właściwości. Kod zazwyczaj ogranicza się do formatowania danych lub konwersji do lub z DTO. Modele prezentacji nie powinny zawierać logiki biznesowej.
• Często przedstawiają zdenormalizowany widok danych. Oznacza to, że często łączą właściwości z wielu DTO.
• Często zawierają właściwości innego typu bazowego niż DTO. Na przykład kwoty w dolarach mogą być reprezentowane jako ciągi znaków, dzięki czemu mogą zawierać przecinki i symbol waluty.
• Często definiowane przez sposób ich użycia, a także przez ich cechy obiektu. Innymi słowy, proste DTO, które jest używane jako model podkładu do renderowania siatki, jest w rzeczywistości również modelem prezentacji w kontekście tej siatki.
Modele prezentacji są używane „w razie potrzeby” i „w razie potrzeby” (podczas gdy DTO są zwykle powiązane ze schematem bazy danych). Model prezentacji może służyć do modelowania danych dla całej strony, siatki na stronie lub listy rozwijanej na siatce na stronie. Modele prezentacji często zawierają właściwości, które są innymi modelami prezentacji. Modele prezentacji są często budowane w celu jednorazowego użytku, takiego jak renderowanie określonej siatki na jednej stronie.
Przykładowy model prezentacji:
Zobacz modele
Model widoku jest podobny do modelu prezentacji, ponieważ jest klasą pomocniczą do renderowania widoku. Jednak bardzo różni się od modelu prezentacji lub DTO pod względem budowy. Modele widoku często zawierają te same właściwości co modele prezentacji i DTO, dlatego często są mylone.
Charakterystyka modeli widoków:
• Są jedynym źródłem danych używanych do renderowania strony lub ekranu. Zwykle oznacza to, że model widoku ujawni każdą właściwość, której każda formant na stronie będzie musiał poprawnie wyrenderować. Utworzenie modelu widoku pojedynczego źródła danych dla widoku znacznie poprawia jego możliwości i wartość do testowania jednostkowego.
• Są obiektami złożonymi, które zawierają właściwości składające się z danych aplikacji oraz właściwości używane przez kod aplikacji. Ta cecha jest kluczowa przy projektowaniu modelu widoku do ponownego użycia i została omówiona w poniższych przykładach.
• Zawierać kod aplikacji. Wyświetl modele zwykle zawierają metody wywoływane podczas renderowania i podczas interakcji użytkownika ze stroną. Ten kod zazwyczaj dotyczy obsługi zdarzeń, animacji, widoczności elementów sterujących, stylizacji itp.
• Zawierają kod wywołujący usługi biznesowe w celu odzyskania danych lub wysłania ich do serwera bazy danych. Ten kod jest często błędnie umieszczony w kontrolerze. Wywoływanie usług biznesowych z kontrolera zwykle ogranicza przydatność modelu widoku do testowania jednostkowego. Żeby było jasne, same modele przeglądania nie powinny zawierać logiki biznesowej, ale powinny nawiązywać połączenia z usługami, które zawierają logikę biznesową.
• Często zawierają właściwości, które są innymi modelami widoku dla innych stron lub ekranów.
• Są zapisywane „na stronę” lub „na ekran”. Unikalny model widoku jest zwykle zapisywany dla każdej strony lub ekranu w aplikacji.
• Zwykle wywodzą się z klasy podstawowej, ponieważ większość stron i ekranów ma wspólne właściwości.
Zobacz skład modelu
Jak wspomniano wcześniej, modele widoków są obiektami złożonymi, ponieważ łączą właściwości aplikacji i właściwości danych biznesowych w jednym obiekcie. Przykłady często używanych właściwości aplikacji używanych w modelach widoku to:
• Właściwości używane do wyświetlania stanu aplikacji, takie jak komunikaty o błędach, nazwa użytkownika, status itp.
• Właściwości używane do formatowania, wyświetlania, stylizacji lub animacji formantów.
• Właściwości używane do wiązania danych, takie jak obiekty listy i właściwości przechowujące dane pośrednie, które są wprowadzane przez użytkownika.
Poniższe przykłady pokazują, dlaczego złożona natura modeli widoków jest ważna i jak najlepiej skonstruować model widoku tak wydajny i wielokrotnego użytku.
Załóżmy, że piszemy aplikację internetową. Jednym z wymagań projektu aplikacji jest to, że tytuł strony, nazwa użytkownika i nazwa aplikacji muszą być wyświetlane na każdej stronie. Jeśli chcemy utworzyć stronę do wyświetlania obiektu zamówienia prezentacji, możemy zmodyfikować model prezentacji w następujący sposób:
Ten projekt może działać… ale co, jeśli chcemy stworzyć stronę, na której będzie wyświetlana lista zamówień? Właściwości PageTitle, UserName i ApplicationName zostaną powtórzone i nie będą działać. A co jeśli chcemy zdefiniować logikę na poziomie strony w konstruktorze klasy? Nie możemy tego dłużej robić, jeśli utworzymy instancję dla każdego zamówienia, które zostanie wyświetlone.
Skład nad dziedziczeniem
Oto sposób, w jaki możemy zmienić fakturę modelu prezentacji zamówienia, tak aby stał się on prawdziwym modelem widoku i będzie przydatny do wyświetlania pojedynczego obiektu PresentationOrder lub kolekcji obiektów PresentationOrder:
Patrząc na powyższe dwie klasy, widzimy, że jednym ze sposobów myślenia o modelu widoku jest to, że jest to model prezentacji, który zawiera inny model prezentacji jako właściwość. Model prezentacji najwyższego poziomu (tj. Model widoku) zawiera właściwości istotne dla strony lub aplikacji, podczas gdy model prezentacji (właściwość) zawiera właściwości istotne dla danych aplikacji.
Możemy pójść o krok dalej i stworzyć klasę modelu widoku podstawowego, która może być używana nie tylko w przypadku PresentationOrders, ale także w każdej innej klasie:
Teraz możemy uprościć naszą PresentationOrderVM w następujący sposób:
Możemy sprawić, że nasz BaseViewModel będzie jeszcze bardziej przydatny, czyniąc go ogólnym:
Teraz nasze wdrożenia są łatwe:
źródło
MyViewModel<MyPresModel>
Jeśli masz właściwości specyficzne dla widoku i niezwiązane z magazynem DB / Service / Data, dobrą praktyką jest używanie ViewModels. Powiedzmy, że chcesz pozostawić zaznaczone pole wyboru na podstawie pola DB (lub dwóch), ale samo pole DB nie jest wartością logiczną. Chociaż możliwe jest utworzenie tych właściwości w samym Modelu i ukrycie go przed powiązaniem z danymi, możesz nie chcieć zaśmiecać Modelu w zależności od ilości takich pól i transakcji.
Jeśli jest za mało danych i / lub transformacji specyficznych dla widoku, możesz użyć samego modelu
źródło
Nie przeczytałem wszystkich postów, ale wydaje się, że w każdej odpowiedzi brakuje jednej koncepcji, która naprawdę pomogła mi „zdobyć” ...
Jeśli model jest podobny do tabeli bazy danych , to ViewModel jest podobny do widoku bazy danych - widok zwykle zwraca albo małe ilości danych z jednej tabeli, albo złożone zestawy danych z wielu tabel (złączeń).
Używam ViewModels do przekazywania informacji do widoku / formularza, a następnie przesyłam te dane do prawidłowego modelu, gdy formularz przesyła z powrotem do kontrolera - bardzo przydatne do przechowywania list (IEnumerable).
źródło
MVC nie ma modelu widoku: ma model, widok i kontroler. Viewmodel jest częścią MVVM (Model-View-Viewmodel). MVVM pochodzi z Modelu prezentacji i jest spopularyzowany w WPF. Powinien również istnieć model w MVVM, ale większość ludzi całkowicie nie rozumie sensu tego wzoru i będą mieli tylko widok i model widoku. Model w MVC jest podobny do modelu w MVVM.
W MVC proces dzieli się na 3 różne obowiązki:
MVC nie jest bardzo odpowiedni do aplikacji internetowych. Jest to wzór wprowadzony przez Smalltalk do tworzenia aplikacji komputerowych. Środowisko sieciowe zachowuje się zupełnie inaczej. Nie ma sensu kopiować 40-letniej koncepcji z pulpitu i wklejać ją do środowiska sieciowego. Jednak wiele osób uważa, że jest to w porządku, ponieważ ich aplikacja kompiluje się i zwraca prawidłowe wartości. To moim zdaniem nie wystarczy, aby zadeklarować pewien wybór projektu jako w porządku.
Przykładem modelu w aplikacji internetowej może być:
Kontroler może używać tego w następujący sposób:
Metody kontrolera i modele będą małe, łatwe do przetestowania i do rzeczy.
źródło
Wyświetl model a to prosta klasa, która może zawierać więcej niż jedną właściwość klasy. Używamy go do dziedziczenia wszystkich wymaganych właściwości, np. Mam dwie klasy Student i Przedmiot
Teraz chcemy wyświetlać rekordy imię i nazwisko ucznia oraz nazwę przedmiotu w widoku (w MVC), ale nie można dodać więcej niż jednej klasy, np .:
powyższy kod zgłosi błąd ...
Teraz tworzymy jedną klasę i możemy nadać jej dowolną nazwę, ale ten format „XyzViewModel” ułatwi zrozumienie. Jest to koncepcja dziedziczenia. Teraz tworzymy trzecią klasę o następującej nazwie:
Teraz używamy tego ViewModel w widoku
Teraz jesteśmy w stanie uzyskać dostęp do wszystkich właściwości StudentViewModel i odziedziczonej klasy w View.
źródło
Wiele dużych przykładów, wyjaśnię w jasny i chrupiący sposób.
ViewModel = Model utworzony w celu obsługi widoku.
Widok ASP.NET MVC nie może mieć więcej niż jednego modelu, więc jeśli musimy wyświetlić właściwości z więcej niż jednego modelu w widoku, nie jest to możliwe. ViewModel służy temu celowi.
Model widoku to klasa modelu, która może przechowywać tylko te właściwości, które są wymagane dla widoku. Może także zawierać właściwości z więcej niż jednego elementu (tabel) bazy danych. Jak sama nazwa wskazuje, ten model jest tworzony zgodnie z wymaganiami widoku.
Kilka przykładów widoków modeli znajduje się poniżej
ViewModel może być również używany do wstawiania, aktualizowania rekordów w więcej niż jednej encji, jednak głównym zastosowaniem ViewModel jest wyświetlanie kolumn z wielu encji (modelu) w jednym widoku.
Sposób tworzenia ViewModel jest taki sam jak tworzenie modelu, sposób tworzenia widoku dla Viewmodel jest taki sam jak tworzenie widoku dla modelu.
Oto mały przykład danych listy przy użyciu ViewModel .
Mam nadzieję, że to się przyda.
źródło
ViewModel to obejście, które załatwia konceptualną niezręczność frameworka MVC. Reprezentuje 4. warstwę w 3-warstwowej architekturze Model-View-Controller. gdy Model (model domeny) nie jest odpowiedni, zbyt duży (większy niż 2-3 pola) dla Widoku, tworzymy mniejszy ViewModel, aby przekazać go do Widoku.
źródło
Model widoku jest koncepcyjnym modelem danych. Jego zastosowaniem jest na przykład uzyskanie podzbioru lub połączenie danych z różnych tabel.
Możesz chcieć tylko określonych właściwości, więc pozwala to tylko ładować te, a nie dodatkowe niepotrzebne właściwości
źródło
Projektowanie ViewModel
Prezentacja modelu widoku w widoku
Praca z działaniem
źródło
View Model to klasa, której możemy użyć do renderowania danych w View. Załóżmy, że masz dwa podmioty Place i PlaceCategory i chcesz uzyskać dostęp do danych z obu podmiotów za pomocą jednego modelu, a następnie korzystamy z ViewModel.
Tak więc w powyższym przykładzie Place i Category to dwa różne podmioty, a ViewCodel PlaceCategory to ViewModel, którego możemy użyć w View.
źródło
Jeśli chcesz przestudiować kod, jak skonfigurować aplikację internetową „Baseline” za pomocą ViewModels, radzę pobrać ten kod na GitHub: https://github.com/ajsaulsberry/BlipAjax . Opracowałem aplikacje dla dużych przedsiębiorstw. Gdy to zrobisz, problematyczne jest ustawienie dobrej architektury, która obsługuje wszystkie funkcje „ViewModel”. Myślę, że dzięki BlipAjax będziesz miał bardzo dobrą „linię bazową” na początek. To tylko prosta strona internetowa, ale świetna w swojej prostocie. Podoba mi się sposób, w jaki używali języka angielskiego, aby wskazać, co jest naprawdę potrzebne w aplikacji.
źródło