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

Данное руководство устарело. Актуальное руководство: Руководство по ASP.NET Core 7

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

Рассмотрим некоторые ситуации передачи данных в контроллер.

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

Пусть у нас есть метод, который принимает массив:

public IActionResult GetData(string[] items)
{
    string result = "";
    foreach (var item in items)
        result += item + "; ";
    return Content(result);
}

Этот метод обрабатывает запросы GET, поэтому данные можно передать ему через строку запроса через название параметра:

http://localhost:54274/Home/GetData?items=volga&items=dnepr&items=don

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

http://localhost:54274/Home/GetData?items[0]=volga&items[2]=dnepr&items[1]=don

Можно просто ограничиться индексами:

http://localhost:54274/Home/GetData?[0]=volga&[2]=dnepr&[1]=don

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

<form method="post">
    <p>
        <input type="text" name="items" />
    </p>
    <p>
        <input type="text" name="items" />
    </p>
    <p>
        <input type="text" name="items" />
    </p>
    <p>
        <input type="submit" value="Отправить" />
    </p>
</form>

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

<form method="post">
    <p>
        <input type="text" name="items[0]" />
    </p>
    <p>
        <input type="text" name="items[2]" />
    </p>
    <p>
        <input type="text" name="items[1]" />
    </p>
    <p>
        <input type="submit" value="Отправить" />
    </p>
</form>

Или вовсе ограничиться индексами:

<form method="post">
    <p>
        <input type="text" name="[0]" />
    </p>
    <p>
        <input type="text" name="[2]" />
    </p>
    <p>
        <input type="text" name="[1]" />
    </p>
    <p>
        <input type="submit" value="Отправить" />
    </p>
</form>

Аналогично массивам будут передаваться и списки типа List.

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

Пусть некоторый метод получает в качестве параметра объект Dictionary:

public IActionResult GetData(Dictionary<string,string> items)
{
    string result = "";
    foreach (var item in items)
        result += item.Key + "= " + item.Value + "; ";
    return Content(result);
}

Для отправки данных мы можем использовать строку запроса:

http://localhost:54274/Home/GetData?items[germany]=berlin&items[france]=paris&items[spain]=madrid

Каждый отдельный элемент этой строки типа items[germany]=berlin будет представлять элемент словаря, где items - название словаря, "germany" - ключ, а "berlin" - значение.

Аналогично мы могли бы отправить данные через форму:

<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>

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

Пусть у нас есть две модели:

public class Phone
{
    public int Id { get; set; }
    public string Name { get; set; }
    public Company Manufacturer { get; set; }
    public decimal Price { get; set; }
}
public class Company
{
    public int Id { get; set; }
    public string Name { get; set; }
}

Пусть у нас есть метод, в котором мы хотим получить объект Phone:

public IActionResult GetPhone(Phone myPhone)
{
    return Content($"Name: {myPhone?.Name}  Price:{myPhone.Price}  Company: {myPhone?.Manufacturer?.Name}");
}

С помощью строки запроса мы можем передать ему значения следующим образом:

http://localhost:54274/Home/GetPhone?myPhone.Price=24000&myPhone.Name=Nexus5X&myPhone.Manufacturer.Name=LG
Установка модели в ASP.NET Core

То есть в данном случае параметр метода называется myPhone, поэтому, например, для установки цены в строке запроса используется параметр myPhone.Price=24000. Но необязательно использовать имя параметра, ограничившись только названиями свойств:

http://localhost:54274/Home/GetPhone?Price=24000&Name=Nexus5X&Manufacturer.Name=LG

Аналогичным образом мы могли бы передать значения через форму:

<form method="post">
    <p>
        <label>Модель</label><br />
        <input type="text" name="myPhone.Name" />
    </p>
    <p>
        <label>Цена</label><br />
        <input type="number" name="myPhone.Price" />
    </p>
    <p>
        <label>Производитель</label><br />
        <input type="text" name="myPhone.Manufacturer.Name" />
    </p>
    <p>
        <input type="submit" value="Отправить" />
    </p>
</form>

Здесь опять же идет связка по атрибуту name. Значение name="myPhone.Price" указывает, что данное поле будет привязано к свойству Price параметра myPhone. Однако опять же необязательно использовать название параметра:

<form method="post">
    <p>
        <label>Модель</label><br />
        <input type="text" name="Name" />
    </p>
    <p>
        <label>Цена</label><br />
        <input type="number" name="Price" />
    </p>
    <p>
        <label>Производитель</label><br />
        <input type="text" name="Manufacturer.Name" />
    </p>
    <p>
        <input type="submit" value="Отправить" />
    </p>
</form>

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

Продолжим работу с теми же моделями Phone и Company, и, допустим, у нас есть метод, который принимает массив или список объектов Phone:

public IActionResult GetPhones(Phone[] phones)
{
    string result = "";
    foreach (var p in phones)
        result = $"{result}{p.Name} - {p.Price} - {p.Manufacturer?.Name} \n";
    return Content(result);
}

С помощью строки запроса мы можем передать данные следующим образом:

http://localhost:54274/Home/GetPhones?phones[0].Name=Lumia950&phones[0].Price=30000&phones[0].Manufacturer.Name=Microsoft&phones[1].Name=iPhone6S&phones[1].Price=50000&phones[1].Manufacturer.Name=Apple

Опять же можно сократить, убрав название параметра и оставив только индексы:

http://localhost:54274/Home/GetPhones?[0].Name=Lumia950&[0].Price=30000&[0].Manufacturer.Name=Microsoft&[1].Name=iPhone6S&[1].Price=50000&[1].Manufacturer.Name=Apple

Но, конечно, подобные данные, лучше все таки передавать через формы. Передача через формы будет аналогична. Допустим, нам надо передать два объекта:

<form method="post">
    @for(int i=0;i<2;i++)
    {
        <div class="phone">
            <h3>Модель № @(i+1)</h3>
            <p>
                <label>Название</label><br />
                <input type="text" name="phones[@i].Name" />
            </p>
            <p>
                <label>Цена</label><br />
                <input type="number" name="phones[@i].Price" />
            </p>
            <p>
                <label>Производитель</label><br />
                <input type="text" name="phones[@i].Manufacturer.Name" />
            </p>
        </div>
    }
    
    <p>
        <input type="submit" value="Отправить" />
    </p>
</form>

Здесь создается два набора полей, каждый из которых предназначен для одного объекта Phone:

Передача сложных моделей в ASP.NET Core Отправка сложных моделей в ASP.NET MVC Core

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

<form method="post">
    @for(int i=0;i<2;i++)
    {
        <div class="phone">
            <h3>Модель № @(i+1)</h3>
            <p>
                <label>Название</label><br />
                <input type="text" name="[@i].Name" />
            </p>
            <p>
                <label>Цена</label><br />
                <input type="number" name="[@i].Price" />
            </p>
            <p>
                <label>Производитель</label><br />
                <input type="text" name="[@i].Manufacturer.Name" />
            </p>
        </div>
    }
    
    <p>
        <input type="submit" value="Отправить" />
    </p>
</form>
Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850