Данное руководство устарело. Актуальное руководство: Руководство по ASP.NET Core 7
Продолжим работу с проектом из прошлой теме. В ней был создан и протестирован контроллер UsersController. Теперь создадим для него визуальную часть, которая будет представлять веб-страницу. То есть из веб-страницы мы будем отправлять запросы к контроллеру и обрабатывать ответ от контроллера.
Для создания веб-клиента добавим в проект папку wwwroot и затем в ней определим новый элемент HTML Page, который назовем "index.html":
Затем изменим класс Startup:
using Microsoft.AspNetCore.Builder; using Microsoft.Extensions.DependencyInjection; using Microsoft.EntityFrameworkCore; using WebAPIApp.Models; namespace WebAPIApp { public class Startup { public void ConfigureServices(IServiceCollection services) { string con = "Server=(localdb)\\mssqllocaldb;Database=usersdbstore;Trusted_Connection=True;"; // устанавливаем контекст данных services.AddDbContext<UsersContext>(options => options.UseSqlServer(con)); services.AddControllers(); // используем контроллеры без представлений } public void Configure(IApplicationBuilder app) { app.UseDeveloperExceptionPage(); app.UseDefaultFiles(); app.UseStaticFiles(); app.UseRouting(); app.UseEndpoints(endpoints => { endpoints.MapControllers(); }); } } }
Здесь в метод Configure()
были добавлены два вызова для работы со статическими файлами:
app.UseDefaultFiles(); app.UseStaticFiles();
Благодаря этому мы сможем обратиться напрямую к веб-странице, например, по пути http://localhost:xxxx/index.html. Для этого изменим файл index.html:
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width" /> <title>Список пользователей</title> <link href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.0/css/bootstrap.min.css" rel="stylesheet" /> </head> <body> <h2>Список пользователей</h2> <form name="userForm"> <input type="hidden" name="id" value="0" /> <div class="form-group col-md-5"> <label for="name">Имя:</label> <input class="form-control" name="name" /> </div> <div class="form-group col-md-5"> <label for="age">Возраст:</label> <input class="form-control" name="age" type="number" /> </div> <div class="panel-body"> <button type="submit" id="submit" class="btn btn-primary">Сохранить</button> <a id="reset" class="btn btn-primary">Сбросить</a> </div> </form> <table class="table table-condensed table-striped col-md-6"> <thead><tr><th>Id</th><th>Имя</th><th>возраст</th><th></th></tr></thead> <tbody> </tbody> </table> <div>2019 © Metanit.com</div> <script> // Получение всех пользователей async function GetUsers() { // отправляет запрос и получаем ответ const response = await fetch("/api/users", { method: "GET", headers: { "Accept": "application/json" } }); // если запрос прошел нормально if (response.ok === true) { // получаем данные const users = await response.json(); let rows = document.querySelector("tbody"); users.forEach(user => { // добавляем полученные элементы в таблицу rows.append(row(user)); }); } } // Получение одного пользователя async function GetUser(id) { const response = await fetch("/api/users/" + id, { method: "GET", headers: { "Accept": "application/json" } }); if (response.ok === true) { const user = await response.json(); const form = document.forms["userForm"]; form.elements["id"].value = user.id; form.elements["name"].value = user.name; form.elements["age"].value = user.age; } } // Добавление пользователя async function CreateUser(userName, userAge) { const response = await fetch("api/users", { method: "POST", headers: { "Accept": "application/json", "Content-Type": "application/json" }, body: JSON.stringify({ name: userName, age: parseInt(userAge, 10) }) }); if (response.ok === true) { const user = await response.json(); reset(); document.querySelector("tbody").append(row(user)); } } // Изменение пользователя async function EditUser(userId, userName, userAge) { const response = await fetch("api/users", { method: "PUT", headers: { "Accept": "application/json", "Content-Type": "application/json" }, body: JSON.stringify({ id: parseInt(userId, 10), name: userName, age: parseInt(userAge, 10) }) }); if (response.ok === true) { const user = await response.json(); reset(); document.querySelector("tr[data-rowid='" + user.id + "']").replaceWith(row(user)); } } // Удаление пользователя async function DeleteUser(id) { const response = await fetch("/api/users/" + id, { method: "DELETE", headers: { "Accept": "application/json" } }); if (response.ok === true) { const user = await response.json(); document.querySelector("tr[data-rowid='" + user.id + "']").remove(); } } // сброс формы function reset() { const form = document.forms["userForm"]; form.reset(); form.elements["id"].value = 0; } // создание строки для таблицы function row(user) { const tr = document.createElement("tr"); tr.setAttribute("data-rowid", user.id); const idTd = document.createElement("td"); idTd.append(user.id); tr.append(idTd); const nameTd = document.createElement("td"); nameTd.append(user.name); tr.append(nameTd); const ageTd = document.createElement("td"); ageTd.append(user.age); tr.append(ageTd); const linksTd = document.createElement("td"); const editLink = document.createElement("a"); editLink.setAttribute("data-id", user.id); editLink.setAttribute("style", "cursor:pointer;padding:15px;"); editLink.append("Изменить"); editLink.addEventListener("click", e => { e.preventDefault(); GetUser(user.id); }); linksTd.append(editLink); const removeLink = document.createElement("a"); removeLink.setAttribute("data-id", user.id); removeLink.setAttribute("style", "cursor:pointer;padding:15px;"); removeLink.append("Удалить"); removeLink.addEventListener("click", e => { e.preventDefault(); DeleteUser(user.id); }); linksTd.append(removeLink); tr.appendChild(linksTd); return tr; } // сброс значений формы document.getElementById("reset").click(function (e) { e.preventDefault(); reset(); }) // отправка формы document.forms["userForm"].addEventListener("submit", e => { e.preventDefault(); const form = document.forms["userForm"]; const id = form.elements["id"].value; const name = form.elements["name"].value; const age = form.elements["age"].value; if (id == 0) CreateUser(name, age); else EditUser(id, name, age); }); // загрузка пользователей GetUsers(); </script> </body> </html>
Основная логика здесь заключена в коде javascript. При загрузке страницы в браузере получаем все объекты из БД с помощью функции GetUsers:
async function GetUsers() { const response = await fetch("/api/users", { method: "GET", headers: { "Accept": "application/json" } }); if (response.ok === true) { const users = await response.json(); let rows = document.querySelector("tbody"); users.forEach(user => { rows.append(row(user)); }); } }
Для добавления строк в таблицу используется функция row()
, которая возвращает строку. В этой строке будут определены ссылки для изменения и удаления пользователя.
Ссылка для изменения пользователя с помощью функции GetUser()
получает с сервера выделенного пользователя:
async function GetUser(id) { const response = await fetch("/api/users/" + id, { method: "GET", headers: { "Accept": "application/json" } }); if (response.ok === true) { const user = await response.json(); const form = document.forms["userForm"]; form.elements["id"].value = user.id; form.elements["name"].value = user.name; form.elements["age"].value = user.age; } }
И выделенный пользователь добавляется в форму над таблицей. Эта же форма применяется и для добавления объекта. С помощью скрытого поля, которое хранит id пользователя, мы можем узнать, какое действие выполняется - добавление или редактирование. Если id равен 0, то выполняется функция CreateUser, которая отправляет данные в POST-запросе:
async function CreateUser(userName, userAge) { const response = await fetch("api/users", { method: "POST", headers: { "Accept": "application/json", "Content-Type": "application/json" }, body: JSON.stringify({ name: userName, age: parseInt(userAge, 10) }) }); if (response.ok === true) { const user = await response.json(); reset(); document.querySelector("tbody").append(row(user)); } }
Если же ранее пользователь был загружен на форму, и в скрытом поле сохранился его id, то выполняется функция EditUser, которая отправляет PUT-запрос:
async function EditUser(userId, userName, userAge) { const response = await fetch("api/users", { method: "PUT", headers: { "Accept": "application/json", "Content-Type": "application/json" }, body: JSON.stringify({ id: parseInt(userId, 10), name: userName, age: parseInt(userAge, 10) }) }); if (response.ok === true) { const user = await response.json(); reset(); document.querySelector("tr[data-rowid='" + user.id + "']").replaceWith(row(user)); } }
При нажатии на ссылку "Удалить" выполняется DELETE-запрос, который по id удаляет пользователя.