Czym jest ViewModel w MVC?

Jestem nowy w ASP.NET MVC. Mam problem ze zrozumieniem celu ViewModel.

Co to jest ViewModel i dlaczego potrzebujemy ViewModel do ASP.NET aplikacja MVC?

Jeśli dostanę dobry przykład na temat jego działania i wyjaśnienia, to byłoby lepiej.

Author: Mukyuu, 2012-06-16

15 answers

A view model reprezentuje dane, które chcesz wyświetlić na widoku / stronie, niezależnie od tego, czy są używane do tekstu statycznego, czy do wartości wejściowych (takich jak Pola tekstowe i listy rozwijane), które można dodać do bazy danych (lub edytować). To coś innego niż twój domain model. Jest to model widoku.

Powiedzmy, że masz klasę Employee, która reprezentuje twój model domeny pracownika i zawiera następujące właściwości (unikalny identyfikator, imię, nazwisko i datę utworzony):

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 domeny tym, że modele widoku zawierają tylko dane (reprezentowane przez właściwości), których chcesz użyć w widoku. Na przykład, powiedzmy, że chcesz dodać nowy rekord pracownika, twój model widoku może wyglądać tak:

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 są również w modelu domeny pracowniczej. Dlaczego możesz o to zapytać? Id może nie być ustawione z widoku, może być auto generowane przez tabelę pracowników. I DateCreated może być również ustawiony w procedurze składowanej lub w warstwie usług Twojej aplikacji. Tak więc Id i {[13] } nie są potrzebne w modelu widoku. Możesz chcieć wyświetlić te dwie właściwości, gdy wyświetlasz dane pracownika (pracownika, który został już przechwycony) jako tekst statyczny.

Podczas ładowania widoku / strony, metoda create action w kontrolerze pracownika utworzy instancję tego modelu widoku, wypełniając dowolne pola, jeśli w tym celu należy przesłać 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 i silnika widoku Razor):

@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 byłaby zatem wykonywana tylko na FirstName i LastName. Używając FluentValidation możesz mieć walidację 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");
     }
}

I z adnotacjami do danych może 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; }
}

Kluczową rzeczą do zapamiętania jest to, że model widoku reprezentuje tylko dane, które ty chcesz użyć , nic więcej. Możesz sobie wyobrazić cały niepotrzebny kod i walidację, jeśli masz model domeny z 30 właściwościami i chcesz zaktualizować tylko jedną wartość. Biorąc pod uwagę ten scenariusz, w modelu widoku będzie tylko jedna wartość/właściwość, a nie wszystkie właściwości znajdujące się w obiekcie domain.

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 na temat dodawania nowego rekordu pracownika. Poza dodaniem tylko imienia i nazwiska możesz również dodać dział pracownika. Ta lista działów będzie pochodzić z Departments tabeli. Więc teraz masz dane z tabel Employees i Departments w modelu jednego widoku. Następnie musisz dodać dwie następujące właściwości do modelu widoku i wypeł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łoby się to zbytnio od mojego przykładu powyżej. Utwórz model widoku, nazwij go na przykład EditEmployeeViewModel. Mają tylko dane, które chcesz edytować w tym modelu widoku, takie jak imię i nazwisko. Edytuj Dane i kliknij przycisk Wyślij. Nie martwiłbym się zbytnio o Pole Id, ponieważ wartość Id prawdopodobnie będzie w adresie URL, na przykład:

http://www.yourwebsite.com/Employee/Edit/3

Weź to Id i prześlij do warstwy repozytorium wraz z wartościami imienia i nazwiska.

Podczas usuwania rekordu, Zwykle postępuję zgodnie z ta sama ścieżka jak w modelu widoku edycji. Chciałbym również mieć adres URL, na przykład:

http://www.yourwebsite.com/Employee/Delete/3

Gdy Widok ładuje się po raz pierwszy, pobieram dane pracownika z bazy danych za pomocą Id z 3. Chciałbym wtedy po prostu wyświetlać statyczny tekst na moim widoku / stronie, aby użytkownik mógł zobaczyć, jaki pracownik jest usuwany. Gdy użytkownik kliknie przycisk Delete, użyłbym Id wartości 3 i przekazał ją do warstwy repozytorium. Potrzebujesz tylko Id, aby usunąć rekord z stolik.

Kolejna kwestia, tak naprawdę nie potrzebujesz modelu widoku dla każdej akcji. Jeśli są to proste dane, to w porządku byłoby używać tylko EmployeeViewModel. Jeśli są to złożone widoki/strony i różnią się od siebie, sugerowałbym użycie oddzielnych modeli widoków dla każdego z nich.

Mam nadzieję, że to usunie wszelkie nieporozumienia, które miałeś na temat modeli widoku i modeli domen.

 638
Author: Brendan Vogt,
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
2019-05-17 06:04:45

Model widoku jest klasą reprezentującą 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 Razora):

@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 pobierany po przesłaniu formularza, z komunikatami walidacyjnymi):

Jak widać, model widoku ma wiele ról:

  • wyświetl dokumenty modeli widok składający się tylko z pól, które są reprezentowane w widoku.
  • modele widoku mogą zawierać określone reguły walidacji za pomocą adnotacji do danych lub IDataErrorInfo.
  • model widoku określa, jak powinien wyglądać widok (dla LabelFor,EditorFor,DisplayFor pomocnicy).
  • modele widoku mogą łączyć wartości z różnych jednostek bazy danych.
  • możesz łatwo określić szablony wyświetlania modeli widoku i używać ich ponownie w wielu miejscach za pomocą pomocy DisplayFor lub EditorFor.

Inny przykład modelu widoku i jego pobierania: chcemy wyświetlić 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 encji 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; }
}

Pobranie:

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
} 
 134
Author: LukLed,
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
2014-08-20 19:09:11

Edit: zaktualizowałem tę odpowiedź na moim blogu:

Http://www.samwheat.com/post/The-function-of-ViewModels-in-MVC-web-development

Moja odpowiedź jest trochę długa, ale myślę, że ważne jest, aby porównać modele widoku do innych typów powszechnie używanych modeli, aby zrozumieć, dlaczego są różne i dlaczego są konieczne.

Aby podsumować i odpowiedzieć bezpośrednio na zadane pytanie:

Ogólnie rzecz biorąc, model widoku jest obiektem, który zawiera wszystkie właściwości i metody niezbędne do renderowania widoku. Właściwości modelu widoku są często zwią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. Modele widoku zapewniają wygodny obiekt do przekazania do silnika renderującego w celu utworzenia strony HTML. Jednym z wielu powodów korzystania z modelu widoku jest to, że modele widoku umożliwiają jednostkowe testowanie niektórych zadań prezentacji, takich jak jako Obsługa wprowadzania danych przez użytkownika, walidacja danych, pobieranie danych do wyświetlania itp.

Oto porównanie modeli encji (a.ka. DTOs a. ka. modele), modele prezentacji i modele widoku.

Obiekty transmisji danych vel "Model"

Data Transfer Object (Dto) jest klasą z właściwościami, które pasują do schematu tabeli w bazie danych. Dto są nazwane ze względu na ich powszechne użycie do przesyłania danych do i z magazynu danych.
Charakterystyka DTOs:

  • są obiekty biznesowe – ich definicja zależy od danych aplikacji.
  • zazwyczaj zawierają tylko właściwości-bez kodu.
  • używany głównie do transportu danych do i z bazy danych.
  • właściwości dokładnie lub ściśle pasują do pól w określonej tabeli w magazynie danych.

Tabele baz danych są zwykle znormalizowane, dlatego też DTOs są zwykle znormalizowane. To sprawia, że są one ograniczone do prezentacji danych. Jednak dla niektórych prostych struktur danych, często radzą sobie całkiem dobrze.

Oto dwa przykłady tego, jak DTOs może wyglądać:

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 klasa narzędzia , która służy do renderowania danych na ekranie lub 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 reprezentują denormalizowany widok danych.

Charakterystyka prezentacji Modele:

  • są obiektami biznesowymi – ich definicja zależy od danych aplikacji.
  • zawierają głównie właściwości. Kod jest zwykle ograniczony do formatowania danych lub konwersji ich do lub z DTO. Modele prezentacji nie powinny zawierać logiki biznesowej.
  • często prezentują denormalizowany 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, jak również ich właściwości obiektu. Innymi słowy, prosty DTO, który jest używany jako model zaplecza 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 być używany do modelowania danych dla całej strony, siatki na stronie lub rozwijanej siatki na stronie. Modele prezentacji często zawierają właściwości, które są innymi modelami prezentacji. Modele prezentacji są często konstruowane do celów jednorazowego użytku, takich 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, który jest klasą pomocniczą do renderowania widoku. Jednak jest to bardzo różne z modelu prezentacji lub DTO w jaki sposób jest skonstruowany. Modele widoku często zawierają te same właściwości co modele prezentacji i Dto i z tego powodu są często mylone jedna z drugą.

Charakterystyka modeli widoku:

  • są pojedynczym źródłem danych używanych do renderowania strony lub ekranu. Zazwyczaj oznacza to, że model widoku ujawni każdą właściwość, którą Dowolna kontrola na stronie będzie musiała renderować poprawnie. Czyniąc model widoku pojedynczym źródło danych dla widoku znacznie poprawia jego możliwości i wartość dla testów jednostkowych.
  • obiektami złożonymi, które zawierają właściwości, które składają się z danych aplikacji, jak również właściwości, które są używane przez kod aplikacji. Ta cecha jest kluczowa przy projektowaniu modelu widoku pod kątem możliwości ponownego użycia i jest omówiona w poniższych przykładach.
  • zawiera kod aplikacji. Modele widoku zazwyczaj zawierają metody, które są wywoływane podczas renderowania i gdy użytkownik jest interakcja ze stroną. Ten kod zazwyczaj odnosi się do obsługi zdarzeń, animacji, widoczności elementów sterujących, stylizacji itp.
  • zawierają kod, który wywołuje usługi biznesowe w celu pobrania danych lub wysłania ich na serwer bazy danych. Kod ten jest często błędnie umieszczany w kontrolerze. Wywołanie usług biznesowych z kontrolera zwykle ogranicza przydatność modelu widoku do testów jednostkowych. Aby było jasne, same modele view nie powinny zawierać logiki biznesowej, ale powinny wykonywanie połączeń do usług, 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 zazwyczaj zapisywany dla każdej strony lub ekranu w aplikacji.
  • zazwyczaj wywodzą się z klasy bazowej, ponieważ większość stron i ekranów ma wspólne właściwości.

Zobacz Skład Modelu

Jak wspomniano wcześniej, modele widoku są złożone obiekty, ponieważ łączą właściwości aplikacji i właściwości danych biznesowych na jednym obiekcie. Przykłady powszechnie używanych właściwości aplikacji, które są używane w modelach widoku to:

  • właściwości, które są używane do wyświetlania stanu aplikacji, takich jak komunikaty o błędach, nazwa użytkownika, stan itp.
  • właściwości używane do formatowania, wyświetlania, stylizacji i animowania kontrolek.
  • właściwości używane do wiązania danych, takie jak obiekty listy i właściwości zawierające dane pośrednie, które jest wprowadzany przez użytkownika.

Poniższe przykłady pokazują, dlaczego złożony charakter modeli widoków jest ważny i jak najlepiej skonstruować model widoku, który jest 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ę wyświetlającą obiekt kolejności prezentacji, możemy zmodyfikować model prezentacji jako następuje:

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 zadział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 staną się nieporęczne do pracy. A co jeśli chcemy zdefiniować jakąś logikę na poziomie strony w konstruktorze klasy? Nie możemy już tego robić, jeśli utworzymy instancję dla każdego zamówienia, które będzie wyświetlane.

skład nad dziedziczeniem

Oto sposób, w jaki możemy model prezentacji kolejności jest uwzględniany w taki sposób, aby stał się prawdziwym modelem widoku i będzie przydatny do wyświetlenia 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 (np. model widoku) zawiera właściwości, które są istotne dla strony lub aplikacji, podczas gdy model prezentacji (właściwość) zawiera właściwości, które są istotne dla danych aplikacji.

Możemy pójść o krok dalej i stworzyć klasę modelu widoku bazowego, która może być używana nie tylko dla PresentationOrders, ale także dla każdej innej klasy:

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ą prezentację 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 model BaseViewModel będzie jeszcze bardziej użyteczny, czyniąc go generycznym:]}
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 implementacje są bez wysiłku:

public class PresentationOrderVM : BaseViewModel<PresentationOrder>
{
    // done!
}

public class PresentationOrderVM : BaseViewModel<List<PresentationOrder>>
{
    // done!
}
 84
Author: Sam,
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
2020-08-31 19:56:36

Jeśli masz właściwości specyficzne dla widoku, a nie związane z DB / Service / Data store, dobrym rozwiązaniem jest używanie ViewModels. Powiedzmy, że chcesz zostawić pole wyboru zaznaczone na podstawie pola DB (lub dwóch), ale samo pole DB nie jest logiczne. Chociaż możliwe jest tworzenie tych właściwości w samym modelu i ukrywanie ich 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 dane specyficzne dla widoku i / lub przekształcenia, można użyć samego modelu

 22
Author: fozylet,
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
2012-06-16 14:44:39

Nie przeczytałem wszystkich postów, ale każda odpowiedź wydaje się brakować jednej koncepcji, która naprawdę pomogła mi "dostać"...

Jeśli Model jest podobny do bazy danych Tabela, Następnie ViewModel jest podobny do bazy danych widok - widok zazwyczaj zwraca niewielkie ilości danych z jednej tabeli lub złożone zestawy danych z wielu tabel (złączeń).

Używam ViewModels, aby przekazać informacje do widoku / formularza,a następnie przenieść te dane do poprawnego Model gdy formularz wysyła z powrotem do kontrolera - również bardzo przydatne do przechowywania list (IEnumerable).

 19
Author: halfacreSal,
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
2016-09-09 20:53:25

MVC nie ma modelu widoku: ma model, widok i kontroler. Viewmodel jest częścią MVVM (Model-View-Viewmodel). MVVM wywodzi się z modelu prezentacji i jest spopularyzowany w WPF. W MVVM powinien być również model, ale większość ludzi całkowicie pomija punkt tego wzoru i będą mieli tylko widok i viewmodel. Model w MVC jest podobny do modelu w MVVM.

W MVC Proces jest podzielony na 3 różne zadania:

  • widok jest odpowiedzialny za przedstawienie danych użytkownikowi
  • kontroler jest odpowiedzialny za przepływ strony
  • model odpowiada za logikę biznesową

MVC nie nadaje się do aplikacji internetowych. Jest to wzorzec wprowadzony przez Smalltalk do tworzenia aplikacji desktopowych. Środowisko internetowe zachowuje się zupełnie inaczej. Nie ma większego sensu kopiowanie 40-letniej koncepcji z pulpitu i wklejanie jej do środowiska internetowego. Jednak wiele osób myśli jest to w porządku, ponieważ ich aplikacja kompiluje i zwraca prawidłowe wartości. To jest, moim zdaniem, za mało, aby określić pewien wybór projektu jako ok.

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ć go 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");
        }
    }
}

Twoje metody kontrolera i twoje modele będą małe, łatwe do przetestowania i do rzeczy.

 11
Author: Jeroen,
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
2015-12-03 16:10:22

Widok model A jest prostą klasą, 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.]}

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 nazwy ucznia i nazwy przedmiotu w widoku (w MVC), ale nie jest możliwe dodanie więcej niż jednej klasy, takiej jak:

 @model ProjectName.Model.Student  
 @model ProjectName.Model.Subject

Powyższy kod spowoduje błąd...

Teraz tworzymy jedną klasę i możemy nadać jej dowolną nazwę, ale ten format "XyzViewModel" sprawi, że łatwiej zrozumieć. 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 widoku.

 11
Author: Mayank,
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
2016-05-31 11:49:13

Wiele dużych przykładów, pozwól mi wyjaśnić w jasny i chrupiący sposób.

ViewModel = Model, który jest tworzony do obsługi widoku.

ASP.NET widok 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 jest klasą modelu, która może przechowywać tylko te właściwości, które są wymagane dla widoku. Może również zawierać właściwości z więcej niż jednego podmiotu (tabele) bazy danych. Jak sama nazwa wskazuje, model ten jest tworzony zgodnie z wymaganiami widoku.

Kilka przykładów modeli widoków znajduje się poniżej

  • aby wyświetlić dane z więcej niż encji na stronie widoku - możemy utworzyć Zobacz model i mieć właściwości wszystkich encji, dla których chcemy do listy danych. Dołącz do tych jednostek bazy danych i ustaw model widoku właściwości i powrót do widoku, aby pokazać DANE różnych encje w jednej formie tabelarycznej
  • model widoku może definiować tylko określone pola jednego podmiotu, który jest wymagane dla widoku.

ViewModel może być również używany do wstawiania, aktualizowania rekordów do więcej niż jednego 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 listy danych za pomocą ViewModel .

Mam nadzieję, że to się przyda.

 10
Author: Sheo Narayan,
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
2016-01-29 07:46:26

ViewModel jest obejściem, które łata pojęciową niezdarność frameworku MVC. Reprezentuje czwartą warstwę w trójwarstwowej architekturze Model-widok-kontroler. gdy Model (model domeny) nie jest odpowiedni, zbyt duży (większy niż 2-3 pola) dla widoku, tworzymy mniejszy model ViewModel, aby przekazać go do widoku.

 6
Author: gsivanov,
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
2019-05-07 20:40:26

Model widoku jest klasą, której możemy użyć do renderowania danych w widoku. Załóżmy, że masz dwa encje Place i PlaceCategory i chcesz uzyskać dostęp do danych z obu encji za pomocą jednego modelu, a następnie używamy 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 miejsce i kategoria to dwa różne encje, a PlaceCategory viewmodel to ViewModel, którego możemy użyć w widoku.

 2
Author: Sagar Shinde,
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
2019-01-19 07:30:28

Model widoku jest koncepcyjnym modelem danych. Jego użycie polega na pobraniu podzbioru lub łączeniu danych z różnych tabel.

Możesz chcieć tylko określonych właściwości, więc pozwala to ładować tylko te, a nie dodatkowe właściwości unneccesary

 1
Author: ,
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
2018-09-21 09:16:41
  • ViewModel zawiera pola reprezentowane w widoku (dla LabelFor, EditorFor, DisplayFor helpers)
  • ViewModel może mieć określone reguły walidacji za pomocą adnotacji do danych lub IDataErrorInfo.
  • ViewModel może mieć wiele elementów lub obiektów z różnych danych Modele lub źródło danych.

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 viewmodel 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 Akcja

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);
} 
  1. w ViewModel umieść tylko te pola / dane,które chcesz wyświetlić widok / strona.
  2. ponieważ view reperteses właściwości ViewModel, stąd jest łatwy do renderowania i konserwacji.
  3. Użyj mapera, gdy ViewModel staje się bardziej złożony.
 1
Author: wild coder,
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
2018-11-10 07:44:01

Jeśli chcesz przestudiować Kod jak skonfigurować" bazową " aplikację webową z ViewModels mogę doradzić, aby pobrać ten kod na GitHub: https://github.com/ajsaulsberry/BlipAjax . opracowałem duże aplikacje korporacyjne. Kiedy to zrobisz, problematyczne jest skonfigurowanie dobrej architektury, która obsługuje całą tę funkcjonalność "ViewModel". Myślę, że z BlipAjax będziesz miał bardzo dobry "baseline" na początek. To po prostu prosta strona internetowa, ale świetna w swojej prostocie. Podoba mi się sposób, w jaki używali język angielski, aby wskazać, co naprawdę potrzebne w aplikacji.

 1
Author: Herman Van Der Blom,
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
2019-10-14 07:49:54

ViewModel jest modelem zawierającym pola do użycia w widoku mvc. Używanie ViewModel dla widoku ma następujące zalety:

  • jako model bazy danych (Klasa Entity) zawiera dane pojedynczej tabeli. Jeśli wymagane są dane z wielu tabel, pojedynczy model widoku może mieć wiele pól tabel.
  • Użytkownik nie może wchodzić w interakcje bezpośrednio z modelem bazy danych, więc warstwa lub model bazy danych jest zabezpieczona.
  • jest używany do pobierania danych z modelu bazy danych przez repozytorium i przekazywania do widoku. Podobnie, to wykorzystuje do delegowania danych do modelu bazy danych w celu aktualizacji rekordów bazy danych.
 1
Author: Sh.Imran,
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
2020-08-16 18:24:09

Model widoku jest taki sam jak Twój datamodel, ale możesz dodać do niego 2 lub więcej klas modeli danych. Zgodnie z tym musisz zmienić kontroler, aby przyjmować 2 modele na raz

 0
Author: Kunal Samal,
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
2020-11-24 06:44:16