Данное руководство устарело. Актуальное руководство: Руководство по ASP.NET Core 7
Вместе с запросом приложению могут приходить различные данные. И чтобы получить эти данные, мы можем использовать разные способы. Самым распространенным способом считается применение параметров.
Определение в методах контроллера параметров ничем не отличается от определения параметров в языке 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:
Если метод принимает несколько параметров:
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.
Кроме 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}"; }