internal SelectList GetMakes(IMakeRepo makeRepo)
=> new SelectList(makeRepo.GetAll(), nameof(Make.Id), nameof(Make.Name));
Метод действия Create() для GET
Метод действия
Create()
для
GET
помещает в словарь
ViewData
список
SelectList
с записями
Make
и отправляет его представлению
Create
:
[HttpGet]
public IActionResult Create([FromServices] IMakeRepo makeRepo)
{
ViewData["MakeId"] = GetMakes(makeRepo);
return View();
}
Форму создания можно просмотреть по ссылке
/Cars/Create
(рис. 31.7).
Метод действия Create() для POST
Метод действия
Create()
для
POST
применяет неявную привязку модели для создания сущности
Car
из значений формы. Вот его код:
[HttpPost]
[ValidateAntiForgeryToken]
public IActionResult Create([FromServices] IMakeRepo makeRepo, Car car)
{
if (ModelState.IsValid)
{
_repo.Add(car);
return RedirectToAction(nameof(Details),new {id = car.Id});
}
ViewData["MakeId"] = GetMakes(makeRepo);
return View(car);
}
Атрибут
HttpPost
помечает метод как конечную точку приложения для маршрута
Cars/Create
, когда запросом является
POST
. Атрибут
ValidateAntiForgeryToken
, использует значение скрытого элемента ввода для
__RequestVerificationToken
чтобы сократить количество атак на сайт.
Экземпляр реализации
IMakeRepo
внедряется в метод из контейнера DI. Поскольку внедрение осуществляется в метод, применяется атрибут
FromServices
. Как вы наверняка помните, атрибут
FromServices
сообщает механизму привязки о том, чтобы он не пытался привязывать этот тип, и позволяет контейнеру DI узнать о необходимости создания экземпляра класса.
Сущность
Car
неявно привязывается к данным входящего запроса. Если состояние модели (
ModelState
) допустимо, тогда сущность
Car
добавляется в базу данных и пользователь перенаправляется на метод действия
Details()
с использованием вновь созданного идентификатора
Car
в качестве параметра маршрута. Такой шаблон называется "отправка-перенаправление-получение" (
Post-Redirect-Get
). Пользователь выполняет отправку с помощью метода
HttpPost(Create()
) и затем перенаправляется на метод
HttpGet(Details()
), что предотвращает повторную отправку браузером запроса
POST
, если пользователь решит обновить страницу.
Если состояние модели не является допустимым, то список
SelectList
с записями
Make
добавляется в объект
ViewData
и сущность, которая была отправлена, посылается обратно представлению
Create
. Состояние модели тоже неявно отправляется представлению, так что могут быть отображены любые ошибки.
Представление Edit
Создайте в каталоге
Views\Cars
новый файл представления по имени
Edit.cshtml
. Удалите весь сгенерированный код и добавьте следующую разметку:
@model Car
@{
ViewData["Title"] = "Edit";
}
<h1>Edit @Model.PetName</h1>
<hr />
<div class="row">
<div class="col-md-4">
<form asp-area="" asp-controller="Cars" asp-action="Edit"
asp-route-id="@Model.Id">
@Html.EditorForModel()
<b> <input type="hidden" asp-for="Id" /></b>
<b> <input type="hidden" asp-for="TimeStamp" /></b>
<div class="form-group">
<button type="submit" class="btn btn-primary">
Save <i class="fas fa-save"></i>
</button> |
<item-list></item-list>
</div>
</form>
</div>
</div>
@section Scripts {
<partial name="_ValidationScriptsPartial" />
}
В представлении также применяется вспомогательная функция
@Html.EditorForModel()
и частичное представление
_ValidationScriptsPartial
. Однако оно еще содержит два скрытых элемента ввода для
Id
и
TimeStamp
. Они будут отправляться вместе с остальными данными формы, но не должны редактироваться пользователями. Без значений
Id
и
TimeStamp
не удалось бы сохранять изменения.