Данное руководство устарело. Актуальное руководство: Руководство по ASP.NET Core 7
Для обработки запроса каждая страница может использовать методы OnGet/OnPost/OnPut и так далее, то есть такие методы, которые предназначены для определенного вида запросов. Однако что если нам необходимо определить на странице для разных ситуаций несколько методов для обработки запроса одного и того же типа запросов (GET или POST)? В этом случае мы можем добавить в код страницы дополнительные обработчики запросов.
Например, пусть в проекте определен класс Person, который представляет данные:
public class Person { public string Name { get; set; } public int Age { get; set; } }
И пусть в проекте есть страница Razor Person.cshtml и связанный с ней файл кода Person.cshtml.cs.
Пусть Person.cshtml.cs содержит следующее определение класса PersonModel:
using System.Collections.Generic; using System.Linq; using Microsoft.AspNetCore.Mvc.RazorPages; using RazorPagesApp.Models; namespace RazorPagesApp.Pages { public class PersonModel : PageModel { List<Person> people; public List<Person> DisplayedPeople { get; set; } public PersonModel() { people = new List<Person>() { new Person{ Name="Tom", Age=23}, new Person {Name = "Sam", Age=25}, new Person {Name="Bob", Age=23}, new Person{Name="Tom", Age=25} }; } public void OnGet() { DisplayedPeople = people; } public void OnGetByName(string name) { DisplayedPeople = people.Where(p => p.Name.Contains(name)).ToList(); } public void OnGetByAge(int age) { DisplayedPeople = people.Where(p => p.Age==age).ToList(); } } }
Класс содержит некоторые начальные данные в переменной people - список объектов Person. При стандартном get-запросе в свойство DisplayedPeople передается весь этот список.
И также определены два метода - обработчики для фильтрации списка по имени и возрасту объекта Person. Так как оба этих обработчики будут также обрабатывать запросы get, то их название начинается с префикса OnGet.
На странице Person.cshtml выводится переданный из PersonModel список:
@page @model PersonModel @using RazorPagesApp.Models <h2>Список пользователей</h2> <table class="table"> <tr><td>Name</td><td>Age</td></tr> @foreach(Person person in Model.DisplayedPeople) { <tr> <td>@person.Name</td> <td>@person.Age</td> </tr> } </table>
И при обычном запросе к странице сработает метод OnGet, поэтому на страницу будет выведен полный список:
Теперь обратимся к конкретному обработчику. Для этого в строку запроса передается параметр "handler" с указанием имени обработчика. Причем именем обработчика считается та часть названия метода, которая идет после префикса OnGet:
В данном случае обращение идет к обработчику OnGetByName. Поскольку он принимает параметр name, то через строку запроса для этого параметра передается значение: http://localhost:44306/Person?handler=ByName&name=Tom.
Не всегда может устроить добавление названия обработчика через строку запроса, наподобие ?handler=ByName. В этом случае можно передать название обработчика через параметр маршрута. Для этого изменим код страницы Person.cshtml:
@page "{handler?}" @model PersonModel @using RazorPagesApp.Models <h2>Список пользователей</h2> <table class="table"> <tr><td>Name</td><td>Age</td></tr> @foreach(Person person in Model.DisplayedPeople) { <tr> <td>@person.Name</td> <td>@person.Age</td> </tr> } </table>
Вопросительный знак после названия параметра "{handler?}" указывает, что данный параметр является необязательным. И в этом случае можно просто указать в url последним сегментом название обработчика:
Подобным образом мы можем использовать обработчики для для обработки запросов POST - посылать данные по адесам, которые отличаются по параметру handler и прочим параметрам строки запроса. Но кроме того, мы можем задавать явным образом нужный обработчик с помощью параметра asp-page-handler. Например, изменим код PersonModel:
using System.Collections.Generic; using System.Linq; using Microsoft.AspNetCore.Mvc.RazorPages; using RazorPagesApp.Models; namespace RazorPagesApp.Pages { public class PersonModel : PageModel { List<Person> people; public List<Person> DisplayedPeople { get; set; } public PersonModel() { people = new List<Person>() { new Person{ Name="Tom", Age=23}, new Person {Name = "Sam", Age=25}, new Person {Name="Bob", Age=23}, new Person{Name="Tom", Age=25} }; } public void OnGet() { DisplayedPeople = people; } public void OnPostGreaterThan(int age) { DisplayedPeople = people.Where(p => p.Age > age).ToList(); } public void OnPostLessThan(int age) { DisplayedPeople = people.Where(p => p.Age < age).ToList(); } } }
Обработчик OnPostGreaterThan находит пользователей, у которых возраст больше определенного, а обработчик OnPostLessThan, наоборот, находит пользователей, у которых возраст меньше, чем определенный.
Изменим код страницы Person.cshtml:
@page "{handler?}" @model PersonModel @using RazorPagesApp.Models <h2>Список пользователей</h2> <form method="POST"> <input type="number" name="age" /> <input type="submit" asp-page-handler="GreaterThan" value="Старше" /> <input type="submit" asp-page-handler="LessThan" value="Младше" /> </form> <table class="table"> <tr><td>Name</td><td>Age</td></tr> @foreach(Person person in Model.DisplayedPeople) { <tr> <td>@person.Name</td> <td>@person.Age</td> </tr> } </table>
На странице определена форма, но в зависимости от того, на какую кнопку мы нажмем, введенное значение будет улетать тому или иному обработчику.