Контроллеры ASP.NET Core MVC. Обработка форм

При разработке приложений в ASP.NET Core MVC активно используются различные веб-формы — форма регистрации нового пользователя, входа в систему, загрузки файлов на сервер и прочие и нам важно, чтобы данные, которые пользователь отправляет нам через форму корректно обрабатывались контроллером.

Получение контроллером данных из формы можно организовать разными способами, в зависимости от наших потребностей. При этом, в ASP.NET Core MVC для получения данных формы действуют те же правила, что и при получении данных из строки запроса, что значительно облегчает нам изучение этой темы.

Тестовое приложение

Так как мы пока ещё не знаем ничего про представления (View) в ASP.NET Core MVC, то наше тестовое приложение будет пока работать с обычным html-файлом, содержащим веб-формы с разным содержимым. Создадим новый проект ASP.NET Core MVC и добавим в папку wwwroot файл data.html со следующим содержимым:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title>Работа с формами в ASP.NET Core</title>
</head>
<body>
    <h3>Передача примитивных типов</h3>
    <form method='post' action='Form/GetPrimitive'>
        <label>Имя:</label><br />
        <input name='name' /><br />
        <label>Возраст:</label><br />
        <input type='number' name='age' /><br />
        <input type='submit' value='Отправить' />
    </form>
</body>
</html>

В этом файле пока определена одна форма с помощью которой пользователь будет отправлять методом POST имя и возраст человека.

Также добавим в папку Controllers новый котроллер — FormController и определим в нем следующее действие:

using Microsoft.AspNetCore.Mvc;

namespace FirstMvcSite.Controllers
{
    public class FormController : Controller
    {
        public async Task Index()
        {
            HttpContext.Response.ContentType = "text/html"; 
            await HttpContext.Response.SendFileAsync(@"wwwroot\data.html");
        }
    }
}

Здесь в методе Index() мы отправляем пользователю файл data.html и, чтобы он отображался в браузере именно как html-страница — устанавливаем заголовок Content-Type:

HttpContext.Response.ContentType = "text/html";

В дальнейшем мы продолжим дописывать файл data.html, а пока разберемся более детально с кодом веб-формы:

<form method='post' action='Form/GetPrimitive'>

в этом тэге мы видим, что для отправки данных будет использоваться метод POST, и запрос отправится по пути «Form/GetPrimitive«, т.е. в контроллер, который будет загружать файл с формой, необходимо будет добавить одноименное действие — GetPrimitive(). Далее мы видим поля формы:

<input name='name' /><br />
<input type='number' name='age' /><br />

это два поля ввода, причем второе поле будет содержат только числа. Здесь нам важно обратить внимание на атрибут name — по значению этого атрибута ASP.NET Core будет связывать значения в полях формы с параметрами в методе контроллера, который будет обрабатывать форму.

Передача примитивных типов данных

Теперь снова вернемся к контроллеру FormController и создадим новое действие:

[HttpPost]
public string GetPrimitive(string name, int age)
{
    return $"{name} - {age}";
}

Здесь стоит обратить внимание на атрибут метода [HttpPost], который означает, что действие контроллера будет обрабатывать только POST-запросы — именно запросом POST и отправляются данные нашей формы в контроллер.

Посмотрим на результат. Загружаем форму и заносим данные:

Жмем кнопку «Отправить»

Как можно видеть, после отправки запроса мы перешли по путь Form/GetPrimitive, то есть, по сути, наш контроллер выполнил одноименное действие и вывел имя и возраст человека.

Передача объектов

Для передачи объектов добавим в папку Models модель из предыдущей части:

namespace FirstMvcSite.Models
{
    public class UserModel
    {
        public int Id { get; set; }
        public string Name { get; set; } = string.Empty;
        public string Email { get; set; } = string.Empty;
    }
}

Теперь добавим в файл data.html следующую форму

<h3>Передача объектов</h3>
<form method='post' action='Form/GetObject'>
    <label>ID:</label><br />
    <input type='number' name='id' /><br />
    <label>Имя:</label><br />
    <input name='name' /><br />
    <label>Email:</label><br />
    <input name='email' /><br />
    <input type='submit' value='Отправить' />
</form>

здесь стоит отметить, что атрибуты name полей ввода полностью совпадают с именами свойств модели (без учёта регистра), а POST-запрос будет отправляться по пути Form/GetObject. Определим новое действие в контроллере FormController:

[HttpPost]
public string GetObject(UserModel model)
{
    return $"{model.Id} - {model.Name} - {model.Email}";
}

Проверим результат:

отправляем форму

Передача массивов

Добавляем в файл data.html следующую форму:

<h3>Передача массивов</h3>
<form method='post' action='Form/GetArray'>
    <label>Первое число:</label><br />
    <input type='number' name='num' /><br />
    <label>Второе число:</label><br />
    <input type='number' name='num' /><br />
    <label>Третье число:</label><br />
    <input type='number' name='num' /><br />
    <input type='submit' value='Отправить' />
</form>

здесь каждое поле формы содержит в атрибуте name одно и тоже значение. Теперь добавим новое действие в контроллер:

[HttpPost]
public string GetArray(int[] num)
{
    return $"Сумма элементов равна: {num.Sum()}";
}

В этом методе имя параметра полностью совпадает со значением атрибута name в полях формы

Проверяем работу:

результат отправки формы

Передача массива объектов

Добавим в data.html новую форму

<h3>Передача массива объектов</h3>
<form method='post' action='Form/GetObjectArray'>
    <b>Первый объект</b>
    <label>ID:</label><br />
    <input type='number' name='user[0].id' /><br />
    <label>Имя:</label><br />
    <input name='user[0].name' /><br />
    <label>Email:</label><br />
    <input name='user[0].email' /><br />
    <hr>
    <b>Второй объект</b>
    <label>ID:</label><br />
    <input type='number' name='user[1].id' /><br />
    <label>Имя:</label><br />
    <input name='user[1].name' /><br />
    <label>Email:</label><br />
    <input name='user[1].email' /><br />
    <hr>
    <b>Третий объект</b>
    <label>ID:</label><br />
    <input type='number' name='user[2].id' /><br />
    <label>Имя:</label><br />
    <input name='user[2].name' /><br />
    <label>Email:</label><br />
    <input name='user[2].email' /><br />

    <input type='submit' value='Отправить' />
</form>

Здесь в атрибуте name указывается имя массива, порядковый номер объекта в массиве и название свойства объекта, например, user[1].id— ID второго объекта в массиве user. Добавим новое действие в контроллер

[HttpPost]
public string GetObjectArray(UserModel[] user) 
{
    return string.Join("\n", user.Select(s => $"{s.Id} - {s.Name} - {s.Email}"));
}

Проверим результат работы:

результат обработки запроса контроллером

Передача словарей

Добавим в файл data.html следующую форму

<h3>Передача словарей</h3>
<form method='post' action='Form/GetDictionary'>
    <b>Первый элемент</b>
    <hr>
    <label>Фрукт:</label><br />
    <input name='dict[fruit]' /><br />
    <b>Второй элемент</b>
    <hr>
    <label>Число:</label><br />
    <input type='number' name='dict[number]' /><br />
    <b>Третий элемент</b>
    <hr>
    <label>Текст:</label><br />
    <input name='dict[text]' /><br />

    <input type='submit' value='Отправить' />
</form>

здесь атрибут name содержит имя словаря и ключа в словаре.

Напишем следующее действие контроллера:

[HttpPost]
public string GetDictionary(Dictionary<string, string> dict)
{
    string result = "";
    foreach (var item in dict)
    {
        result = $"{result} {item.Key} - {item.Value}; ";
    }
    return result;
}

Проверяем работу приложения

результат

Использование свойства HttpContext для обработки форм

Также для получения данных из веб-форм можно использовать свойство HttpContext. Например, добавим в data.html следующую форму:

<h3>Использование свойства HttpContext</h3>
<form method='post' action='Form/GetData'>
    <label>Имя:</label><br />
    <input name='name' /><br />
    <label>Возраст:</label><br />
    <input type='number' name='age' /><br />
    <input type='submit' value='Отправить' />
</form>

и действие контроллера

[HttpPost]
public string GetData()
{
    return $"{HttpContext.Request.Form["name"]} - {HttpContext.Request.Form["age"]}";
}

здесь в метод GetData() уже не требуется передавать никаких параметров, так как сведения о форме получаются напрямую из контекста запроса (свойство Form объекта Request). Для доступа к данным поля мы используем значение атрибута name поля формы.

Итого

Обработка веб-форм в ASP.NET Core MVC, по большому счёту, ничем не отличается от получения данных контроллером из строки параметров запроса. Мы также можем передавать в формах примитивные типы, массивы, массивы объектов, словари и т.д. Важным является правильное задание значение атрибутов name для полей формы. При этом, данные форм мы также можем получать и из свойства HttpContext контроллера.

Подписаться
Уведомить о
guest
0 Комментарий
Старые
Новые Популярные
Межтекстовые Отзывы
Посмотреть все комментарии