Данное руководство устарело. Актуальное руководство: Руководство по ASP.NET Core 7
В прошлой теме мы создали функционал для вывода объектов на веб-страницу, чтобы пользователь смог увидеть все товары и их информацию. Теперь добавим функциональность для оформления заказов. В прошлой теме у нас была определена ссылка на метод Buy контроллера HomeController, который должен выполнять функции по покупке товара. Поэтому добавим в контроллер HomeController следующие методы:
[HttpGet] public IActionResult Buy(int? id) { if (id == null) return RedirectToAction("Index"); ViewBag.PhoneId = id; return View(); } [HttpPost] public string Buy(Order order) { db.Orders.Add(order); // сохраняем в бд все изменения db.SaveChanges(); return "Спасибо, " + order.User + ", за покупку!"; }
Хотя мы добавили два метода, но в целом они составляют одно действие Buy. С помощью атрибутов [HttpGet]
и [HttpPost]
мы можем указать, какой метод какой тип запроса
обрабатывает. В итоге при получении запроса система выберет из них нужный метод. И таким образом, первый метод срабатывает при получении запроса GET, а
второй - при получении запроса POST.
Так как предполагается, что в метод Buy будет передаваться id смартфона, который пользователь хочет купить, то нам надо определить в методе соответствующий
параметр: public IActionResult Buy(int? id)
.
Если в метод вдруг не передано id смартфона, хотя сам метод вызван, в этом случае с помощью вызова RedirectToAction("Index")
выполняем переадресацию на метод Index, который выводит список товаров.
Чтобы передать id смартфона в представление применяется объект ViewBag.
ViewBag представляет такой объект, который позволяет определить любую переменную и передать ей некоторое значение, а затем в представлении извлечь это значение. Так, мы определяем переменную ViewBag.PhoneId, которая и будет хранить id выбранного смартфона.
Теперь добавим представление для этого метода, которое должно выводить форму для оформления заказа. Для этого нажмем правой кнопкой мыши на папку Views/Home и в контекстном меню выберем Add -> New Item:
И затем в открывшемся окне добавления нового элемента выберем Razor View и назовем новый элемент Buy.cshtml, так как по умолчанию названия представлений (не считая расширения файла cshtml) должны соответствовать названию вызывающих их методов:
Созданное по умолчанию представление изменим следующим образом:
@{ Layout = null; } <!DOCTYPE html> <html> <head> <title>Оформление заказа</title> </head> <body> <div> <h3>Форма оформления покупки</h3> <p>Для оформления покупки заполните следующие поля:</p> <form method="post"> <input type="hidden" value="@ViewBag.PhoneId" name="PhoneId" /> <table> <tr> <td>Имя:</td> <td><input type="text" name="User" /> </td> </tr> <tr> <td>Адрес:</td> <td><input type="text" name="Address" /></td> </tr> <tr> <td>Телефон:</td> <td><input type="text" name="ContactPhone" /></td> </tr> <tr><td><input type="submit" value="Отправить" /> </td><td></td></tr> </table> </form> </div> </body> </html>
Данное представление представляет собой форму для ввода данных. И так как в методе мы установили переменную во ViewBag, то в представлении мы ее можем получить. Поскольку нам не надо менять ее значение, то мы его вкладываем в скрытое поле в начале формы.
В итоге при переходе на главной странице по ссылке "/Home/Buy/1" контроллер будет получать запрос к действию Buy, передавая ему в качестве параметра id значение 1. И так как такой запрос представляет тип GET, пользователю будет возвращаться данное представление с формой.
После заполнения формы и нажатия на кнопку форма будет оправляться запросом POST, так как мы его определили в строке
<form method="post">
. Контроллер снова будет получать запрос к действию Buy, но теперь для обработки запроса будет выбираться метод
public string Buy(Order order)
.
Несмотря на то, что на форме у нас простые поля ввода, в post-версии метода Buy мы получаем именно модель Order. Как система MVC угадывает, что мы передали с запросом post информацию о модели Order, а не набор разрозненных значений полей формы? Обратите внимание на поля ввода:
<input type="hidden" value="@ViewBag.PhoneId" name="PhoneId" /> <input type="text" name="User" /> <input type="text" name="Address" /> <input type="text" name="ContactPhone" />
Значение атрибута name у этих полей ввода соответствует названию одного из свойств модели Order. После нажатия кнопки и отправки запроса приложение получает значения этих полей. Для связывания приходящих на сервер данных с параметрами методов фреймворк MVC использует специальный компонент привязчик модели (model binder), который по названию пришедших данных сопоставит их со свойствами модели Order и создаст объект этой модели.
Снова запустим проект. На главной странице выберем какой-нибудь смартфон и нажмем на ссылку "Купить". На форме заполним поля и нажмем кнопку "Отправить".
После нажатия кнопки информация о покупке попадет в базу данных, а в браузер отобразит уведомление: