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

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

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

Вместе с запросом приложению могут приходить различные данные. И чтобы получить эти данные, мы можем использовать разные способы. Самым распространенным способом считается применение параметров.

Определение в методах контроллера параметров ничем не отличается от определения параметров в языке C#. Параметры могут представлять примитивные типы, как int или string, а могут представлять и более сложные классы.

Передавать значения для параметров можно различными способами. При отправке GET-запроса значения передаются через строку запроса. Стандартный get-запрос принимает примерно следующую форму: название_ресурса?параметр1=значение1&параметр2=значение2. Например, определим следующий метод:

public string Hello(int id)
{
    return $"id= {id}";
}

Чтобы передать значение для параметра id, нам надо отправить запрос типа http://localhost:57086/Home/Hello?id=9:

Параметры метода контроллера в ASP.NET MVC Core

Если метод принимает несколько параметров:

public string Square(int a, int h)
{
    double s = a * h / 2;
    return $"Площадь треугольника с основанием {a} и высотой {h} равна {s}";
}

В этом случае мы можем обратиться к действию, набрав в адресной строке Home/Square?a=10&h=3, и приложение выдало бы нам нужный результат.

Если же мы не используем параметры в строке запроса, то для параметров будут передаваться значения по умолчанию. Например, при отправке запроса Home/Square/ параметры a и h будут равны 0. Но на случай подобной ситуации мы можем использовать параметры по умолчанию, которые будут работать, если через строку запроса не передается никаких параметров:

public string Square(int a = 3, int h = 10)
{
    double s = a * h / 2;
    return $"Площадь треугольника с основанием {a} и высотой {h} равна {s}";
}

Система привязки MVC, которую мы позже рассмотрим, сопоставляет параметры запроса и параметры метода по имени. То есть, если в строке запроса идет параметр a, то его значение будет передаваться именно параметру метода, который также называется a. При этом должно быть также соответствие по типу, то есть если параметр метода принимает числовое значение, то и через строку запроса надо передавать для этого параметра число, а не строку.

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

Хотя строка запроса преимущественно используется для передачи данных примитивных типов, но мы также можем принимать более сложные объекты. Например, определим рядом с контроллером класс Geometry:

public class HomeController : Controller
{
	public IActionResult Index()
	{
		return View();
	}
	
    public string Area(Geometry geometry)
    {
        return $"Площадь треугольника с основанием {geometry.Altitude} и высотой {geometry.Height} равна {geometry.GetArea()}";
    }
	
	// остальное содержимое
}
public class Geometry
{
    public int Altitude { get; set; } // основание
    public int Height { get; set; } // высота

    public double GetArea() // вычисление площади треугольника
    {
        return Altitude * Height / 2;
    }
}

Класс Geometry определяет два свойства и метод для подсчета площади. И теперь в контроллере метод Area принимает параметр типа Geometry. Как в этом случае мы можем передать контроллеру данные? Для этого нам надо отправить запрос наподобие следующего http://localhost:57086/Home/Area?altitude=10&height=3. Здесь параметры строки запроса должны соответствовать по имени свойствам объекта. Регистр названий при этом не учитывается:

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

Допустим, метод принимает массив чисел:

public string Sum(int[] nums)
{
    return $"Сумма чисел равна {nums.Sum()}";
}

Чтобы передать значения для массива, нам надо использовалась строку запроса наподобие http://localhost:57086/Home/Sum?nums=1&nums=2&nums=3. В этом случае в массиве nums окажется три элемента.

Теперь изменим метод Sum, чтобы он принимал массив объектов ранее созданного класса Geometry:

public string Sum(Geometry[] geoms)
{
    return $"Сумма площадей равна {geoms.Sum(g=>g.GetArea())}";
}

Данный метод подсчитывает сумму всех площадей в массиве geoms. И чтобы передать в этот метод данные, нам надо использовать запрос типа http://localhost:57086/Home/Sum?geoms[0].altitude=10&geoms[0].height=3&geoms[1].altitude=16&geoms[1].height=2. В этом случае в массиве geoms будут два элемента Geometry.

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

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

Для передачи POST-запросов определим в представлении Index.cshtml, которое должно быть по умолчанию в папке Views/Home, простенькую форму:

<form method="post" action="~/Home/Area">
    <label>Высота:</label><br />
    <input type="number" name="height" /><br />
    <label>Основание:</label><br />
    <input type="number" name="altitude" /><br />
    <input type="submit" value="Отправить" />
</form>

Форма устанавливает метод отправки - post, адрес отправки - Home/Area и два поля ввода чисел.

И чтобы метод Area принимал отправляемые данные, нам надо изменить его код следующим образом:

public class HomeController : Controller
{
	public IActionResult Index()
	{
		return View();
	}
	[HttpPost]
	public string Area(int altitude, int height)
	{
		double square = altitude * height / 2;
		return $"Площадь треугольника с основанием {altitude} и высотой {height} равна {square}";
	}
}

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

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

[HttpPost]
public string Area(Geometry geometry)
{
    return $"Площадь треугольника с основанием {geometry.Altitude} и высотой {geometry.Height} равна {geometry.GetArea()}";
}

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

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

Данные строки запроса доступны через свойство Request.Query, которое представляет объект IQueryCollection. Например:

public string Area()
{
    string altitudeString = Request.Query.FirstOrDefault(p => p.Key == "altitude").Value;
    int altitude = Int32.Parse(altitudeString);

    string heightString = Request.Query.FirstOrDefault(p => p.Key == "height").Value;
    int height = Int32.Parse(heightString);

    double square = altitude * height / 2;
    return $"Площадь треугольника с основанием {altitude} и высотой {height} равна {square}";
}

В данном случае метод Area обрабатывает GET-запросы, и мы можем к нему обратиться через запрос типа http://localhost:57086/Home/Area?altitude=20&height=4.

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

[HttpPost]
public string Area()
{
    string altitudeString = Request.Form.FirstOrDefault(p => p.Key == "altitude").Value;
    int altitude = Int32.Parse(altitudeString);

    string heightString = Request.Form.FirstOrDefault(p =>p.Key == "height").Value;
    int height = Int32.Parse(heightString);

    double square = altitude * height / 2;
    return $"Площадь треугольника с основанием {altitude} и высотой {height} равна {square}";
}
Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850