Язык программирования C#9 и платформа .NET5 - Эндрю Троелсен
Представление Create
Представление Create было начато ранее. Вот его полная разметка:
@model Car
@{
ViewData["Title"] = "Create";
}
<h1>Create a New Car</h1>
<hr/>
<div class="row">
<div class="col-md-4">
<form asp-controller="Cars" asp-action="Create">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
@Html.EditorForModel()
<div class="form-group">
<button type="submit"
class="btn btn-success">Create <i class="fas fa-plus"></i>
</button> |
<item-list></item-list>
</div>
</form>
</div>
</div>
@section Scripts {
<partial name="_ValidationScriptsPartial" />
}
Вспомогательная функция @Html.EditorForModel() использует созданный ранее шаблон отображения (Car.cshtml) для отображения редактора сведений об автомобиле.
В разделе Scripts представления указано частичное представление _ValidationScriptsPartial. Вспомните, что в компоновке этот раздел встречается после загрузки jQuery. Шаблон разделов помогает гарантировать загрузку надлежащих зависимостей до загрузки самого содержимого.
Методы действий Create()
В рамках процесса создания применяются два метода действий: первый (HttpGet) возвращает пустое представление для ввода новой записи, а второй (HttpPut) отправляет значения новой записи.
Вспомогательный метод GetMakes()
Вспомогательный метод GetMakes() возвращает список записей Make в виде экземпляра SelectList и принимает в качестве параметра экземпляр реализации IMakeRepo:
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
Создайте в каталоге ViewsCars новый файл представления по имени 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()
<input type="hidden" asp-for="Id" />
<input type="hidden" asp-for="TimeStamp" />
<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 не удалось бы сохранять изменения.
Методы действий Edit()
В рамках процесса редактирования используются два метода действий: первый (HttpGet) возвращает сущность, подлежащую редактированию, а второй (HttpPut) отправляет значения обновленной записи.
Метод действия Edit() для GET
Метод действия Edit() для GET получает одиночную запись Car с идентификатором Id через оболочку службы и отправляет ее представлению Edit:
[HttpGet("{id?}")]
public IActionResult Edit([FromServices] IMakeRepo makeRepo, int? id)
{
var car = GetOneCar(id);
if (car == null)
{
return NoContent();
}
ViewData["MakeId"] = GetMakes(makeRepo);
return View(car);
}
Маршрут имеет необязательный параметр id, значение которого передается методу с применением параметра id. Экземпляр реализации IMakeRepo внедряется в метод и используется для создания списка SelectList записей Make. Посредством вспомогательного метода GetOneCar() получается запись Car. Если запись Car найти не удалось, тогда метод возвращает ошибку NoContent. В противном случае он добавляет список SelectList записей Make в словарь ViewData и визуализирует представление Edit.
Форму редактирования можно просмотреть по ссылке /Cars/Edit/1 (рис. 31.8).
Метод действия Edit() для POST
Метод действия Edit() для POST аналогичен методу действия Create() для POST с отличиями, описанными после кода метода:
[HttpPost("{id}")]
[ValidateAntiForgeryToken]
public IActionResult Edit([FromServices] IMakeRepo makeRepo, int id, Car car)
{
if