Данное руководство устарело. Актуальное руководство: Руководство по ASP.NET Core 7
Одним из ключевых компонентов паттерна MVC являются модели. Ключевая задача моделей - описание структуры и логики используемых данных.
Как правило, все используемые сущности в приложении выделяются в отдельные модели, которые и описывают структуру каждой сущности. В зависимости от задач и предметной области мы можем выделить различное количество моделей в приложении.
Все модели оформляются как обычные POCO-классы (plain-old CRL objects), то есть обычные классы на языке C#. Например, если мы работаем с приложением интернет-магазина мобильных телефонов, то мы могли бы определить в проекте следующую модель, представляющую телефон:
public class Phone { public int Id { get; set; } public string Name { get; set; } public string Company { get; set; } public int Price { get; set; } }
Модель Phone определяет ряд свойств: уникальный идентификатор Id, название, компанию производителя и цену. Это классическая анемичная модель. Анемичная модель не имеет поведения и хранит только состояние в виде свойств.
Однако модель необязательно должна состоять только из свойств. Кроме того, она может иметь конструктор, какие-нибудь методы, поля, вообщем предствлять стандартный класс на языке C#. Модели, которые также определяют поведение, в противоположность анемичным моделям называют "толстыми" моделями (Rich Domain Model / Fat Model / Thick Model). Например, мы можем уйти от анемичной модели, модифицировав ее следующим образом:
public class Phone { private decimal _discount = 0; public Phone(decimal discount) { this._discount = discount; } public int Id { get; set; } public string Name { get; set; } public string Company { get; set; } public decimal Price { get; set; } public decimal GetPriceWithDiscount() { return this.Price - (this.Price * this._discount); } }
Но какой бы способ описания сущности не был выбран, главное помнить, что его предназначение состоит прежде всего описывать данные. И модель должна описывать только одну сущность, следуя принципу единой ответственности.
В приложении ASP.NET MVC Core модели можно разделить по степени применения на несколько групп:
Модели, объекты которых хранятся в специальных хранилищах данных (например, в базах данных, файлах xml и т.д.)
Модели, которые используются для передачи данных представление или наоборот, для получения данных из представления. Такие модели еще называтся моделями представления
Вспомогательные модели для промежуточных вычислений
Как правило, для хранения моделей создается в проекте отдельная папка Models. Модели представления нередко помещаются в отдельную папку, которая нередко называется ViewModels. В реальности, это могут быть каталоги с любыми называниями, можно помещать модели хоть в корень проекта, но более распространенным стилем являются названия Models и ViewModels.
Например, создадим новый проект ASP.NET Core по типу ASP.NET Core Web App (Model-View-Controller). По умолчанию он уже содержит папку Models, в которой по умолчанию определен класс ErrorViewModel - модель, используемая для вывода информации об ошибках в приложении.
Вначале добавим в эту папку новый класс Company:
public class Company { public int Id { get; set; } public string Name { get; set; } public string Country { get; set; } }
И также добавим в папку Models класс Phone
public class Phone { public int Id { get; set; } public string Name { get; set; } public Company Manufacturer { get; set; } public decimal Price { get; set; } }
Эти модели будут описывать данные, которые мы будем использовать. Эти данные могут храниться в базе данных, но для простоты мы определим их в контроллере. Изменим контроллер HomeController следующим образом:
using System.Collections.Generic; using Microsoft.AspNetCore.Mvc; using ModelsApp.Models; // пространство имен моделей namespace ModelsApp.Controllers { public class HomeController : Controller { List<Phone> phones; public HomeController() { Company apple = new Company { Id = 1, Name = "Apple", Country = "США" }; Company microsoft = new Company { Id = 2, Name = "Samsung", Country = "Республика Корея" }; Company google = new Company { Id = 3, Name = "Google", Country = "США" }; phones = new List<Phone> { new Phone { Id=1, Manufacturer= apple, Name="iPhone X", Price=56000 }, new Phone { Id=2, Manufacturer= apple, Name="iPhone XZ", Price=41000 }, new Phone { Id=3, Manufacturer= microsoft, Name="Galaxy 9", Price=9000 }, new Phone { Id=4, Manufacturer= microsoft, Name="Galaxy 10", Price=40000 }, new Phone { Id=5, Manufacturer= google, Name="Pixel 2", Price=30000 }, new Phone { Id=6, Manufacturer= google, Name="Pixel XL", Price=50000 } }; } public IActionResult Index() { return View(phones); } } }
Список объектом модели передается в представление с помощью метода View()
.
И в конце изменим представление Index.cshtml, которое будет выводить все объекты:
@using ModelsApp.Models @model IEnumerable<Phone> @{ ViewData["Title"] = "Home Page"; } <table class="table"> @foreach (Phone p in Model) { <tr><td>@p.Name</td><td>@p.Manufacturer?.Name</td><td>@p.Price</td></tr> } </table>
И при обращении к приложению веб-станица выведет список моделей: