Содержание
При разработке приложений в 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 контроллера.









