Обработчики страницы Razor Pages

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

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

Для обработки запроса каждая страница может использовать методы 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.

BindProperty в Razor Pages

Пусть 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, поэтому на страницу будет выведен полный список:

Обработчики в Razor Pages в ASP.NET Core

Теперь обратимся к конкретному обработчику. Для этого в строку запроса передается параметр "handler" с указанием имени обработчика. Причем именем обработчика считается та часть названия метода, которая идет после префикса OnGet:

Handlers в Razor Pages в ASP.NET Core

В данном случае обращение идет к обработчику 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 последним сегментом название обработчика:

Передача handler через параметр маршрута в Razor Pages

Обработка форм и запросов POST

Подобным образом мы можем использовать обработчики для для обработки запросов 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>

На странице определена форма, но в зависимости от того, на какую кнопку мы нажмем, введенное значение будет улетать тому или иному обработчику.

POST handlers in Razor Pages in ASP.NET Core
Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850