Кроме получения данных из параметры запроса и из отправленных форм в Razor Pages также можно получать данные из параметров маршрута. И в данном случае важно понимать отличие параметров строки запроса от параметров маршрута. Например:
localhost:5000/Index?id=21 localhost:5000/Index/21
Параметры, которые идут после вопросительного знака в адресе url, представляют параметры строки запроса. А данные, которые разделены в url слешами, представляют параметры маршрута. Один url может содержать как параметры маршрута, так и параметры запроса.
Чтобы определить параметры маршрута, необходимо после на странице после директивы @page определить шаблон маршрута. Например, мы хотим получать из маршрута параметр id:
@page "{id}"
Для получения параметров маршрута на странице Razor и в ее модели применяется словарь RouteData.Values. С помощью ключа - названия параметра можно получить его значение:
object? id = RouteData.Values["id"];
Стоит при этом учитывать, что возвращаемое значение по умолчанию представляет тип object?
Например, у нас есть страница Razor Index.cshtml и код связанной модели IndexModel в файле Index.cshtml.cs:
Например, определим в файле Index.cshtml.cs следующий код:
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.RazorPages; namespace RazorPagesApp.Pages { public class IndexModel : PageModel { public object? Id { get; private set; } public void OnGet() { Id = RouteData.Values["id"]; } } }
Используем на странице Index.cshtml параметр id:
@page "{id}" @model RazorPagesApp.Pages.IndexModel <h2>Id = @Model.Id</h2>
Также можно получить значение параметра непосредственно на странице Index.cshtml:
@page "{id}" @{ var userid = RouteData.Values["id"]; } <h2>Id = @userid</h2>
Также мы можем получить параметры маршрута через одноименные параметры метода OnGet(). Так, изменим модель IndexModel:
using Microsoft.AspNetCore.Mvc.RazorPages; namespace RazorPagesApp.Pages { public class IndexModel : PageModel { public int Id { get; private set; } public void OnGet(int id) { Id = id; } } }
Код страницы Index.cshtml:
@page "{id}" @model RazorPagesApp.Pages.IndexModel <h2>Id = @Model.Id</h2>
Преимуществом такого подхода является то, что инфраструктура Razor Pages может автоматически преобразовать значение к некоторому типу. Так, в данном случае мы получаем параметр маршрута как значение типа int, а не object?.
Если мы возьмем пример выше и обратимся к странице без передачи параметра, то браузер отобразит нам ошибку 404:
В одних сценариях это может приемлимо и даже необходимо, в других, возможно, нежелательно. И на этот случай мы можем установить параметр как необязательный, указав после названия параметра вопросительный знак ?:
@page "{id?}" @model RazorPagesApp.Pages.IndexModel <h2>Id = @Model.Id</h2>
Тогда в методе OnGet мы можем определить параметр как значение nullable-типа:
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.RazorPages; namespace RazorPagesApp.Pages { public class IndexModel : PageModel { public int Id { get; private set; } public void OnGet(int? id) { Id = id ?? 0; } } }
В данном случае если параметр id передан, то свойство Id получает его значение. Если параметр не передан, то свойство Id получает значение 0.
В качестве альтернативы для параметра можно предусмотреть значение по умолчанию:
public void OnGet(int id = 1) { Id = id; }
И также, как и в случае с параметрами строки запроса, мы можем получить значение параметра маршрута, используя атрибут BindProperty:
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.RazorPages; namespace RazorPagesApp.Pages { public class IndexModel : PageModel { [BindProperty(SupportsGet = true)] public int Id { get; set; } } }
При необходимости мы можем передавать несколько параметров маршрута. Каждый параметр заключается в фигурные скобки и отделяется от других параметров слешами:
using Microsoft.AspNetCore.Mvc.RazorPages; namespace RazorPagesApp.Pages { public class IndexModel : PageModel { public string Name { get; set; } = ""; public int Age { get; set; } public void OnGet(string name, int age) { Name = name; Age = age; } } }
В данном случае получаем два параметра - name и age. На странице Index.cshtml определим данные параметры:
@page "{name}/{age}" @model @model RazorPagesApp.Pages.IndexModel <p>Id = @Model.Id</p> <p>Name = @Model.Name</p> <p>Age = @Model.Age</p>
Также оба параметра можно было бы привязать к свойствам:
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.RazorPages; namespace RazorPagesApp.Pages { public class IndexModel : PageModel { [BindProperty(SupportsGet = true)] public string Name { get; set; } = ""; [BindProperty(SupportsGet = true)] public int Age { get; set; } } }
Как и в стандартной модели MVC для параметров маршрутов в Razor Pages можно применять ограничения:
@page "{name:alpha:minlength(3)}/{age:int}" @model PersonModel <p>Name = @Model.Name</p> <p>Age = @Model.Age</p>
В данном случае параметр age должен обязательно представлять целое число, а параметр name может содержать только алфавитные символы, причем не менее трех символов. В данном случае действуют все те же ограничения, что применяются к параметрам маршрута в целом в ASP.NET Core и про которые можно посмотреть в статье Ограничения маршрутов.