Данное руководство устарело. Актуальное руководство: Руководство по ASP.NET Core
Модели, которые используются в приложении, бывают разными. В прошлой теме мы рассмотрели вывод и одновременно фильтрацию объектов Player:
public class Player { public int Id { get; set; } public string Name { get; set; } public int Age { get; set; } public string Position { get; set; } public int? TeamId { get; set; } public Team Team { get; set; } }
Модель Player в данном случае представляет модель домена, ее объекты хранятся в базе данных и чтобы их получить, мы обращаемся через контекст данных к БД. Но в прошлой теме только функциональности этой модели оказалось недостаточно. Для передачи данных в представление нам пришлось создать дополнительную модель:
public class PlayersListViewModel { public IEnumerable<Player> Players { get; set; } public SelectList Teams { get; set; } public SelectList Positions { get; set; } }
Это модель представления или view model, которая предназначена конкретно для вывода данных в некоторое представление. И важно понимать отличие domain model от view model.
Другая часто встречающаяся ситуация - редактирование. Нам надо редактировать игрока, но надо изменить не все свойства, а только часть. Опять же в этом случае создается дополнительная модель представления, которая содержит те свойства, которые надо изменить. Например:
public class PlayerViewModel { public int Id { get; set; } public int Age { get; set; } public string Position { get; set; } }
И представление для редактирования тогда использует не модель Player, а модель PlayerViewModel. Тогда обработка введенных данных могла выглядеть следующим образом:
[HttpPost] public ActionResult Edit(PlayerViewModel playerModel) { Player player = db.Players.Find(playerModel.Id); if (player == null) return HttpNotFound(); player.Position = playerModel.Position; player.Age = playerModel.Age; db.SaveChanges(); return RedirectToAction("Index"); }
В некоторых случаях модель домена может совпадать с моделью представления. Например, при создании нового игрока мы можем определить следующее представление:
@model NavigationProperty.Models.Player @{ ViewBag.Title = "Добавление игрока"; } <h2>Добавление нового игрока</h2> @using (Html.BeginForm()) { <fieldset> <legend>Футболист</legend> @Html.HiddenFor(model => model.Id) <p> Имя игрока <br /> @Html.EditorFor(model => model.Name) </p> <p> Возраст <br /> @Html.EditorFor(model => model.Age) </p> <p> Позиция на поле <br /> @Html.EditorFor(model => model.Position) </p> <p> Команда <br /> @Html.DropDownListFor(model => model.TeamId, ViewBag.Teams as SelectList) </p> <p> <input type="submit" value="Добавить игрока" /> </p> </fieldset> }
Представление использует модель Player, метод контроллера также может получать эту модель и сразу сохранять ее в базу данных. То есть здесь domain model = view model. Для маленьких приложений это вполне допустимо. Но, как правило, такие ситуации в реальных приложениях встречаются не часто и то в основном в очень небольших.
Для больших приложений или даже небольших, но которые постоянно расширяются, подобная ассоциация моделей может вылиться в проблемы с поддержкой и развитием приложения. Поэтому рекомендуется для каждого отдельного представления создавать свою ViewModel.