Поскольку OP спросил, вот пример паттерна ViewModel, или, как я его называю, ASP.NET MVC выполнен правильно.
Так зачем использовать модель, специфичную для вида
- Вы должны передавать только той информации, которая вам нужна.
- Часто вам необходимо добавить дополнительные метаданные представления (например, атрибуты title / description).Они не принадлежат вашим организациям.
- Использование TryUpdateModel / UpdateModel неверно.Не используйте (я объясню почему).
- Очень редко ваши модели представлений будут точно соответствовать вашим сущностям.Люди часто заканчивают тем, что добавляют дополнительную лживость к своим сущностям или (не намного лучше), просто используя ViewBag, а не строго типизированные свойства модели представления.
- Если вы используете ORM, вы можете столкнуться с проблемами с загруженными свойствами LazyN + 1).Ваши представления не должны выдавать запросы.
Мы начнем с простой сущности:
public class Product {
public int Id {get;set;}
public string Name {get;set;}
public string Description {get;set;}
public decimal Price {get;set;}
}
И скажем, у вас есть простая форма, в которой пользователь может только обновить Name
и Description
продукта.Но вы используете (очень жадный) TryUpdateModel.
Поэтому я сам использую любое количество инструментов (например, Fiddler) для создания POST и отправляю следующее:
Name =WhatverIWant & Description = UnluckyFool & Price = 0
Что ж, механизм связывания модели ASP.NET MVC собирается проверить коллекцию входных форм, убедиться, что эти свойства существуют в вашей сущности, и автоматически свяжет их для вас.Поэтому, когда вы вызываете «TryUpdateModel» для сущности, которую вы только что извлекли из вашей базы данных, все соответствующие свойства будут обновлены (включая цену!).Время для новой опции.
Просмотр определенной модели
public class EditProductViewModel {
[HiddenInput]
public Guid Id {get;set;}
[Required]
[DisplayName("Product Name")]
public string Name {get;set;}
[AllowHtml]
[DataType(DataType.MultilineText)]
public string Description {get;set;}
}
Это содержит только свойства, которые нам нужны в нашем представлении.Обратите внимание, что мы также добавили некоторые проверочные атрибуты, отображаемые атрибуты и некоторые специфичные для mvc атрибуты.
Не ограничиваясь тем, что мы имеем в нашей модели представлений, это может сделать ваши представления намного чище.Например, мы могли бы отобразить всю нашу форму редактирования, имея в нашем представлении следующее:
@Html.EditorFor(model => model)
Mvc проверит все те атрибуты, которые мы добавили в нашу модель представления, и автоматически подключит валидацию, меткии правильные поля ввода (т. е. текстовая область для описания).
РАЗМЕЩЕНИЕ формы
[HttpPost]
public ActionResult EditProduct(EditProductViewModel model) {
var product = repository.GetById(model.Id);
if (product == null) {
return HttpNotFound();
}
// input validation
if (ModelState.IsValid) {
// map the properties we **actually** want to update
product.Name = model.Name;
product.Description = model.Description;
repository.Save(product);
return RedirectToAction("index");
}
return View(model)
}
Из этого кода довольно очевидно, что он делает.У нас нет никаких нежелательных эффектов при обновлении нашей сущности, так как мы явно устанавливаем свойства для нашей сущности.
Я надеюсь, что этого достаточно для объяснения шаблона View-Model, чтобы вы захотели его использовать.