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.
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.
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):
public class Employee : IEntity
{
public int Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public DateTime DateCreated { get; set; }
}
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:
public class CreateEmployeeViewModel
{
public string FirstName { get; set; }
public string LastName { get; set; }
}
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. I DateCreated
może być również ustawiony w procedurze przechowywanej lub w warstwie serwisowej aplikacji. Tak Id
i DateCreated
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:
public class EmployeeController : Controller
{
private readonly IEmployeeService employeeService;
public EmployeeController(IEmployeeService employeeService)
{
this.employeeService = employeeService;
}
public ActionResult Create()
{
CreateEmployeeViewModel model = new CreateEmployeeViewModel();
return View(model);
}
public ActionResult Create(CreateEmployeeViewModel model)
{
// Do what ever needs to be done before adding the employee to the database
}
}
Twój widok / strona może wyglądać tak (zakładając, że używasz ASP.NET MVC
iRazor
silnik wyświetlania):
@model MyProject.Web.ViewModels.CreateEmployeeViewModel
<table>
<tr>
<td><b>First Name:</b></td>
<td>@Html.TextBoxFor(m => m.FirstName, new { maxlength = "50", size = "50" })
@Html.ValidationMessageFor(m => m.FirstName)
</td>
</tr>
<tr>
<td><b>Last Name:</b></td>
<td>@Html.TextBoxFor(m => m.LastName, new { maxlength = "50", size = "50" })
@Html.ValidationMessageFor(m => m.LastName)
</td>
</tr>
</table>
Walidacja zostałaby zatem dokonana tylko w dniu FirstName
i LastName
. Korzystanie z FluentValidation możesz mieć sprawdzanie poprawności w następujący sposób:
public class CreateEmployeeViewModelValidator : AbstractValidator<CreateEmployeeViewModel>
{
public CreateEmployeeViewModelValidator()
{
RuleFor(m => m.FirstName)
.NotEmpty()
.WithMessage("First name required")
.Length(1, 50)
.WithMessage("First name must not be greater than 50 characters");
RuleFor(m => m.LastName)
.NotEmpty()
.WithMessage("Last name required")
.Length(1, 50)
.WithMessage("Last name must not be greater than 50 characters");
}
}
A w przypadku adnotacji danych może to wyglądać tak:
public class CreateEmployeeViewModel : ViewModelBase
{
[Display(Name = "First Name")]
[Required(ErrorMessage = "First name required")]
public string FirstName { get; set; }
[Display(Name = "Last Name")]
[Required(ErrorMessage = "Last name required")]
public string LastName { get; set; }
}
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 tabel Employees
i Departments
w jednym modelu widoku. Musisz wtedy dodać następujące dwie właściwości do modelu widoku i zapełnić go danymi:
public int DepartmentId { get; set; }
public IEnumerable<Department> Departments { get; set; }
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 to Id
pole, ponieważ Id
wartość prawdopodobnie będzie w adresie URL, na przykład:
http://www.yourwebsite.com/Employee/Edit/3
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:
http://www.yourwebsite.com/Employee/Delete/3
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ć tylkoEmployeeViewModel
. 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.
Model widoku to klasa reprezentująca model danych używany w określonym widoku. Możemy użyć tej klasy jako modelu strony logowania:
public class LoginPageVM
{
[Required(ErrorMessage = "Are you really trying to login without entering username?")]
[DisplayName("Username/e-mail")]
public string UserName { get; set; }
[Required(ErrorMessage = "Please enter password:)")]
[DisplayName("Password")]
public string Password { get; set; }
[DisplayName("Stay logged in when browser is closed")]
public bool RememberMe { get; set; }
}
Za pomocą tego modelu widoku można zdefiniować widok (silnik widoku Razor):
@model CamelTrap.Models.ViewModels.LoginPageVM
@using (Html.BeginForm()) {
@Html.EditorFor(m => m);
<input type="submit" value="Save" class="submit" />
}
I działania:
[HttpGet]
public ActionResult LoginPage()
{
return View();
}
[HttpPost]
public ActionResult LoginPage(LoginPageVM model)
{
...code to login user to application...
return View(model);
}
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:
public class UserVM {
public int ID { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public bool IsAdministrator { get; set; }
public string MothersName { get; set; }
}
Wyszukiwanie:
var user = db.userRepository.GetUser(id);
var model = new UserVM() {
ID = user.ID,
FirstName = user.FirstName,
LastName = user.LastName,
IsAdministrator = user.Proviledges.IsAdministrator,
MothersName = user.Mother.FirstName + " " + user.Mother.LastName
}
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:
public class Customer
{
public int ID { get; set; }
public string CustomerName { get; set; }
}
public class Order
{
public int ID { get; set; }
public int CustomerID { get; set; }
public DateTime OrderDate { get; set; }
public Decimal OrderAmount { get; set; }
}
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:
public class PresentationOrder
{
public int OrderID { get; set; }
public DateTime OrderDate { get; set; }
public string PrettyDate { get { return OrderDate.ToShortDateString(); } }
public string CustomerName { get; set; }
public Decimal OrderAmount { get; set; }
public string PrettyAmount { get { return string.Format("{0:C}", OrderAmount); } }
}
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:
public class PresentationOrder
{
public string PageTitle { get; set; }
public string UserName { get; set; }
public string ApplicationName { get; set; }
public int OrderID { get; set; }
public DateTime OrderDate { get; set; }
public string PrettyDate { get { return OrderDate.ToShortDateString(); } }
public string CustomerName { get; set; }
public Decimal OrderAmount { get; set; }
public string PrettyAmount { get { return string.Format("{0:C}", OrderAmount); } }
}
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:
public class PresentationOrderVM
{
// Application properties
public string PageTitle { get; set; }
public string UserName { get; set; }
public string ApplicationName { get; set; }
// Business properties
public PresentationOrder Order { get; set; }
}
public class PresentationOrderVM
{
// Application properties
public string PageTitle { get; set; }
public string UserName { get; set; }
public string ApplicationName { get; set; }
// Business properties
public List<PresentationOrder> Orders { get; set; }
}
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:
public class BaseViewModel
{
// Application properties
public string PageTitle { get; set; }
public string UserName { get; set; }
public string ApplicationName { get; set; }
}
Teraz możemy uprościć naszą PresentationOrderVM w następujący sposób:
public class PresentationOrderVM : BaseViewModel
{
// Business properties
public PresentationOrder Order { get; set; }
}
public class PresentationOrderVM : BaseViewModel
{
// Business properties
public List<PresentationOrder> Orders { get; set; }
}
Możemy sprawić, że nasz BaseViewModel będzie jeszcze bardziej przydatny, czyniąc go ogólnym:
public class BaseViewModel<T>
{
// Application properties
public string PageTitle { get; set; }
public string UserName { get; set; }
public string ApplicationName { get; set; }
// Business property
public T BusinessObject { get; set; }
}
Teraz nasze wdrożenia są łatwe:
public class PresentationOrderVM : BaseViewModel<PresentationOrder>
{
// done!
}
public class PresentationOrderVM : BaseViewModel<List<PresentationOrder>>
{
// done!
}
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
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).
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ć:
public class LoginModel
{
private readonly AuthenticationService authentication;
public LoginModel(AuthenticationService authentication)
{
this.authentication = authentication;
}
public bool Login()
{
return authentication.Login(Username, Password);
}
public string Username { get; set; }
public string Password { get; set; }
}
Kontroler może używać tego w następujący sposób:
public class LoginController
{
[HttpPost]
public ActionResult Login(LoginModel model)
{
bool success = model.Login();
if (success)
{
return new RedirectResult("/dashboard");
}
else
{
TempData["message"] = "Invalid username and/or password";
return new RedirectResult("/login");
}
}
}
Metody kontrolera i modele będą małe, łatwe do przetestowania i do rzeczy.
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
Public class Student
{
public int Id {get; set;}
public string Name {get; set;}
}
Public class Subject
{
public int SubjectID {get; set;}
public string SubjectName {get; set;}
}
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 .:
@model ProjectName.Model.Student
@model ProjectName.Model.Subject
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:
public class StudentViewModel:Subject
{
public int ID {get; set;}
public string Name {get; set;}
}
Teraz używamy tego ViewModel w widoku
@model ProjectName.Model.StudentViewModel
Teraz jesteśmy w stanie uzyskać dostęp do wszystkich właściwości StudentViewModel i odziedziczonej klasy w View.
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.
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.
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
Projektowanie ViewModel
public class UserLoginViewModel
{
[Required(ErrorMessage = "Please enter your username")]
[Display(Name = "User Name")]
[MaxLength(50)]
public string UserName { get; set; }
[Required(ErrorMessage = "Please enter your password")]
[Display(Name = "Password")]
[MaxLength(50)]
public string Password { get; set; }
}
Prezentacja modelu widoku w widoku
@model MyModels.UserLoginViewModel
@{
ViewBag.Title = "User Login";
Layout = "~/Views/Shared/_Layout.cshtml";
}
@using (Html.BeginForm())
{
<div class="editor-label">
@Html.LabelFor(m => m.UserName)
</div>
<div class="editor-field">
@Html.TextBoxFor(m => m.UserName)
@Html.ValidationMessageFor(m => m.UserName)
</div>
<div class="editor-label">
@Html.LabelFor(m => m.Password)
</div>
<div class="editor-field">
@Html.PasswordFor(m => m.Password)
@Html.ValidationMessageFor(m => m.Password)
</div>
<p>
<input type="submit" value="Log In" />
</p>
</div>
}
Praca z działaniem
public ActionResult Login()
{
return View();
}
[HttpPost]
public ActionResult Login(UserLoginViewModel user)
{
// To acces data using LINQ
DataClassesDataContext mobjentity = new DataClassesDataContext();
if (ModelState.IsValid)
{
try
{
var q = mobjentity.tblUsers.Where(m => m.UserName == user.UserName && m.Password == user.Password).ToList();
if (q.Count > 0)
{
return RedirectToAction("MyAccount");
}
else
{
ModelState.AddModelError("", "The user name or password provided is incorrect.");
}
}
catch (Exception ex)
{
}
}
return View(user);
}
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.
public class Place
{
public int PlaceId { get; set; }
public string PlaceName { get; set; }
public string Latitude { get; set; }
public string Longitude { get; set; }
public string BestTime { get; set; }
}
public class Category
{
public int ID { get; set; }
public int? PlaceId { get; set; }
public string PlaceCategoryName { get; set; }
public string PlaceCategoryType { get; set; }
}
public class PlaceCategoryviewModel
{
public string PlaceName { get; set; }
public string BestTime { get; set; }
public string PlaceCategoryName { get; set; }
public string PlaceCategoryType { get; set; }
}
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.
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.