Передача данных в контроллер через формы

Последнее обновление: 27.03.2022

Передача данных через формы в запросе POST

Кроме GET-запросов также широко применяются POST-запросы. Как правило, такие запросы отправляются с помощью форм на веб-странице. Но основные принципы передачи данных будут теми же, что и в GET-запросах.

Для передачи POST-запросов определим в следующий контроллер с двумя методами:

using Microsoft.AspNetCore.Mvc;

namespace MvcApp.Controllers
{
    public class HomeController : Controller
    {
        [HttpGet]
        public async Task Index()
        {
            string content = @"<form method='post'>
                <label>Name:</label><br />
                <input name='name' /><br />
                <label>Age:</label><br />
                <input type='number' name='age' /><br />
                <input type='submit' value='Send' />
            </form>";
            Response.ContentType = "text/html;charset=utf-8";
            await Response.WriteAsync(content);
        }
        [HttpPost]
        public string Index(string name, int age) => $"{name}: {age}";
    }
}

Первый метод Index имеет атрибут [HttpGet], поэтому данный метод будет обрабатывать только запросы GET. Для упрощения примера в ответ метод будет возвращать html-код с формой ввода (хотя естественно, для формы html можно было бы определить отдельную html-страницу или представление)

Эта форма содержит два поля ввода. Что важно, первое поле имеет имя "name", которое задается с помощью атрибута "name":

<input name='name' />

Второе поле имеет имя "age":

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

Таким образом, при обращении к методу пользователь увидит в браузере форму ввода. При нажатии на кнопку Send введенные данные будут отправляться на сервер. Поскольку у элемента <form> не задан атрибут action, который устанавливает адрес, то введенные данные отправляются на тот же адрес (то есть по сути методу с тем же именем - методу Index). Но поскольку у формы установлен атрибут method='post', то данные будут отправлять в запросе типа POST. А запросы данного типа обрабатывает второй метод Index:

[HttpPost]
public string Index(string name, int age) => $"{name}: {age}";

Чтобы система могла связать параметры метода и данные формы, необходимо, чтобы атрибуты name у полей формы соответствовали названиям параметров. То есть в данном случае параметры метода Index называются так же, как и поля формы - name и age.

Передача значений в методы контроллера ASP.NET Core MVC через отправку форм в POST-запросе в C#

Получение сложных объектов

При получении данных форм действуют те же правила привязки, что и при получении параметров строки запроса. Поэтому с той же формы можно получить значения в виде сложных объектов, в которых названия свойств соответствуют названиям полей формы:

using Microsoft.AspNetCore.Mvc;

namespace MvcApp.Controllers
{
    public class HomeController : Controller
    {
        public async Task Index()
        {
            string content = @"<form method='post'>
                <label>Name:</label><br />
                <input name='name' /><br />
                <label>Age:</label><br />
                <input type='number' name='age' /><br />
                <input type='submit' value='Send' />
            </form>";
            Response.ContentType = "text/html;charset=utf-8";
            await Response.WriteAsync(content);
        }
        [HttpPost]
        public string Index(Person person) => $"{person.Name}: {person.Age}";
    }
    public record class Person(string Name, int Age);
}

В данном случае поля формы name и age соответствуют по названию свойствам класса Person, поэтому вместо одиночных разрозненных значений мы можем получить отправленную форму в виде объекта Person.

Получение массивов

Для передачи массивов с помощью формы надо создать набор одноименных полей, которые называются по имени массива:

using Microsoft.AspNetCore.Mvc;

namespace MvcApp.Controllers
{
    public class HomeController : Controller
    {
        public async Task Index()
        {
            string form = @"<form method='post'>
                <p><input name='names' /></p>
                <p><input name='names' /></p>
                <p><input name='names' /></p>
                <input type='submit' value='Send' />
            </form>";
            Response.ContentType = "text/html;charset=utf-8";
            await Response.WriteAsync(form);
        }
        [HttpPost]
        public string Index(string[] names)
        {
            string result = "";
            foreach(string name in names)
            {
                result = $"{result} {name}";
            }
            return result;
        }
    }
}

В данном случае на форме, отправляемой пользователю, расположены три поля с именем "names". В итоге при отправке формы будет сформирован массив names из трех элементов, который можно получить во втором методе Index:

Отправка из форм массивов в методы контроллера ASP.NET Core MVC в C#

И также у элементов формы можно было бы явным образом указать индексы:

<form method='post'>
    <p><input name='names[0]' /></p>
    <p><input name='names[2]' /></p>
    <p><input name='names[1]' /></p>
    <input type='submit' value='Send' />
</form>

Также можно было бы вовсе ограничиться одними индексами

<form method='post'>
    <p><input name='[0]' /></p>
    <p><input name='[2]' /></p>
    <p><input name='[1]' /></p>
    <input type='submit' value='Send' />
</form>

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

Передача словарей в метод контроллера аналогична передаче элементов массивов за тем исключением, что для каждого элемента устанавливается ключ:

using Microsoft.AspNetCore.Mvc;

namespace MvcApp.Controllers
{
    public class HomeController : Controller
    {
        [HttpGet]
        public async Task Index()
        {
            string content = @"<form method='post'>
        <p>
            Германия:
            <input type='text' name='items[germany]' />
        </p>
        <p>
            Франция:
            <input type='text' name='items[france]' />
        </p>
        <p>
            Испания:
            <input type='text' name='items[spain]' />
        </p>
        <p>
            <input type='submit' value='Отправить' />
        </p>
    </form>";
            Response.ContentType = "text/html;charset=utf-8";
            await Response.WriteAsync(content);
        }
        [HttpPost]
        public string Index(Dictionary<string, string> items)
        {
            string result = "";
            foreach (var item in items)
            {
                result = $"{result} {item.Key} - {item.Value}; ";
            }
            return result;
        }
    }
}
Отправка из форм словарей Dictionary в методы контроллера ASP.NET Core MVC в C#

Отправка массивов сложных объектов

При отправке массивов сложных объектов на форме также определяется набор полей, где каждое поле привязано к определенному свойству объекта:

using Microsoft.AspNetCore.Mvc;

namespace MvcApp.Controllers
{
    public class HomeController : Controller
    {
        public async Task Index()
        {
            string form = @"<form method='post'>
                <p>
                    Person1 Name:<br/> 
                    <input name='people[0].name' /><br/>
                    Person1 Age:<br/>
                    <input name='people[0].age' />
                </p>
                <p>
                    Person2 Name:<br/> 
                    <input name='people[1].name' /><br/>
                    Person2 Age:<br/>
                    <input name='people[1].age' />
                </p>
                <input type='submit' value='Send' />
            </form>";
            Response.ContentType = "text/html;charset=utf-8";
            await Response.WriteAsync(form);
        }
        [HttpPost]
        public string Index(Person[] people)
        {
            string result = "";
            foreach(Person person in people)
            {
                result = $"{result} \n{person}";
            }
            return result;
        }
    }
    public record class Person(string Name, int Age);
}

В данном случае на форму вводятся значения для свойств Name и Age двух объектов Person. После отправке эти объекты уйдут в виде массива people второму методу Index.

Отправка из форм массивов сложных объектов в методы контроллера ASP.NET Core MVC в C#

Получение данных из контекста запроса

Для получения данных отправленных форм можно использовать свойство Request.Form. Это свойство представляет коллекцию IFormsCollection, где каждый элемент имеет ключ и значение. В качестве ключа элемента выступает название поля формы, а в качестве значения - введенные в это поле данные:

using Microsoft.AspNetCore.Mvc;

namespace MvcApp.Controllers
{
    public class HomeController : Controller
    {
        public async Task Index()
        {
            string content = @"<form method='post' action='/Home/PersonData'>
                   <label>Name:</label><br />
                <input name='name' /><br />
                <label>Age:</label><br />
                <input type='number' name='age' /><br />
                <input type='submit' value='Send' />
            </form>";
            Response.ContentType = "text/html;charset=utf-8";
            await Response.WriteAsync(content);
        }
        [HttpPost]
        public string PersonData()
        {
            string name = Request.Form["name"];
            string age = Request.Form["age"];
            return $"{name}: {age}";
        }
    }
}
Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850