Ограничения маршрутов

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

При обработке запроса система маршрутизации на основании шаблон маршрута автоматически извлекает из строки запроса значения для параметров маршрута вне зависимости от содержимого этих значений. Однако это не всегда бывает удобно. Например, мы хотим, чтобы какой-то параметр представлял только числа, а другой параметр начинался строго с определенного символа. И для этого необходимо задать ограничения маршрута (route constraints).

Ограничения маршрутов выполняюся при парсинге пути запроса, сопоставлении его с шаблоном маршрута и выделении из него значений для параметров маршрута. Ограничения маршрутов применяются для разных задач. Прежде всего они решают, допустимо ли для параметра маршрута значение, которое выделено из пути запроса. Также ограничения маршрута могут решать, можно ли вообще сопоставить путь запроса с определенным маршрутом. Кроме того, ограничения маршрута могут применяться при генерации ссылок.

Вначале рассмотрим следующую ситуацию. Пусть у нас есть следующее приложение:

Imports Microsoft.AspNetCore.Builder
Imports Microsoft.AspNetCore.Http

Module Program
    Sub Main(args As String())

        Dim builder = WebApplication.CreateBuilder(args)
        Dim app = builder.Build()

        app.Map("/users/{id}", Function(id As Integer) $"User Id: {id}")
        app.Map("/", Function(context As HttpContext) "Index Page")

        app.Run()
    End Sub
End Module

Первая конечная точка использует маршрут, который подразумевает наличие параметра id. А в обработчике маршрута мы хотим получить значение этого параметра в виде числа. То есть мы ожидаем, что в пути запроса будет передаваться число, например, "/users/123". Тем не менее мы можем передать вместо числа и строку:

Ограничения маршрутов в ASP.NET Core и Visual Basic .NET

На скриншоте выше обращение идет по адресу "/users/hello". И этот путь запроса в принципе соответствует шаблону маршрута "/users/{id}". В этом случае параметр маршрута id получит значение "hello", а для обработки запроса будет запущено действие

Function(id As Integer) $"User Id: {id}"

Однако параметр id обработчика представляет тип int, а строка "hello" никак не может быть конвертирована в число. Соответственно мы получим ошибку при преобразовании, о чем собственно и говорит скриншот.

Теперь применим ограничения - укажем, что параметр id в маршруте должен представлять тип int:

Imports Microsoft.AspNetCore.Builder
Imports Microsoft.AspNetCore.Http

Module Program
    Sub Main(args As String())

        Dim builder = WebApplication.CreateBuilder(args)
        Dim app = builder.Build()

        app.Map("/users/{id:int}", Function(id As Integer) $"User Id: {id}")
        app.Map("/", Function(context As HttpContext) "Index Page")

        app.Run()
    End Sub
End Module

Для установки ограничения после названия параметра через двоеточие указывается название ограничения. Ограничение int указывает, что параметр должен представлять тип int.

В этом случае нам надо передать этому параметру число:

Установка ограничений для параметров маршрута в ASP.NET Core и Visual Basic .NET

Да, мы по-прежнему можем передавать в пути запроса строку вместо числа:

Установка ограничений для параметров маршрута в ASP.NET Core и Visual Basic .NET

Но в этом случае инфраструктура ASP.NET Core просто не сможет сопоставить данный путь запроса с шаблоном маршрута. И клиент получит ошибку 404, то есть ресурс не найден.

ASP.NET Core предоставляет следующий ряд ограничений маршрута:

  • int

    Соответствие целому числу. Представляет класс IntRouteConstraint

    {id:int}
  • bool. Представляет класс BoolRouteConstraint

    Соответствие значению true или false

    {active:bool}
  • datetime

    Соответствие дате и времени. Представляет класс DateTimeRouteConstraint

    {date:datetime}
  • decimal

    Соответствие значению decimal. Представляет класс DecimalRouteConstraint

    {price:decimal}
  • double

    Соответствие значению типа double. Представляет класс DoubleRouteConstraint

    {weight:double}
  • float

    Соответствие значению типа float. Представляет класс FloatRouteConstraint

    {height:float}
  • guid

    Соответствие значению типа Guid. Представляет класс GuidRouteConstraint

    {id:guid}
  • long

    Соответствие значению типа long. Представляет класс LongRouteConstraint

    {id:long}
  • minlength(value)

    Строка должна иметь символов не меньше value. Представляет класс MinLengthRouteConstraint

    {name:minlength(3)}
  • maxlength(value)

    Строка должна иметь символов не больше value. Представляет класс MaxLengthRouteConstraint

    {name:maxlength(20)}
  • length(value)

    Строка должна иметь ровно столько символов, сколько определено в параметре value. Представляет класс LengthRouteConstraint

    {name:length(10)}
  • length(min, max)

    Строка должна иметь символов не меньше min и не больше max. Представляет класс LengthRouteConstraint

    {name:length(3, 20)}
  • min(value)

    Число должно быть не меньше value. Представляет класс MinRouteConstraint

    {age:min(3)}
  • max(value)

    Число должно быть не больше value. Представляет класс MaxRouteConstraint

    {age:max(20)}
  • range(min, max)

    Число должно быть не меньше min и не больше max. Представляет класс RangeRouteConstraint

    {age:range(18, 99)}
  • alpha

    Строка должна состоять из одного и более алфавитных символов. Представляет класс AlphaRouteConstraint

    {name:alpha}
  • regex(expression)

    Строка должна соответствовать регулярному выражению expression. Представляет класс RegexRouteConstraint

    {phone:regex(^\d{{3}}-\d{{3}}-\d{{4}}$)}
  • required

    Параметр является обязательным, и его значение должно быть определено. Представляет класс RequiredRouteConstraint

    {name:required}

Каждое подобное ограничени представляет определенный класс. При этом ограничения можно комбинировать. При применении нескольких ограничений одновременно, они отделяются друг о друга двоеточием Например:

Imports Microsoft.AspNetCore.Builder
Imports Microsoft.AspNetCore.Http

Module Program
    Sub Main(args As String())

        Dim builder = WebApplication.CreateBuilder(args)
        Dim app = builder.Build()

        app.Map("/users/{name:alpha:minlength(2)}/{age:int:range(1, 110)}",
                Function(name As String, age As Integer) $"User Age: {age} {Environment.NewLine}User Name:{name}")

        app.Map("/phonebook/{phone:regex(^7-\d{{3}}-\d{{3}}-\d{{4}}$)}",
                Function(phone As String) $"Phone: {phone}")

        app.Map("/", Function(context As HttpContext) "Index Page")

        app.Run()
    End Sub
End Module

Первая конечная точка использует шаблон маршрута

"/users/{name:alpha:minlength(2)}/{age:int:range(1, 110)}"

Здесь предполагается, что параметр name принимает только алфавитные символы, а его минимальная длина должна представлять два символа. Второй же параметр маршрута - age должен представлять целое число и должен находиться в диапазоне между 1 и 110:

Длина строка параметров маршрута в ASP.NET Core и Visual Basic .NET

Вторая конечная точка использует шаблон маршрута

"/phonebook/{phone:regex(^7-\d{{3}}-\d{{3}}-\d{{4}}$)}"

Параметр phone принимает номер телефона в формате 7-ххх-ххх-хххх, любые другие форматы будут некорректными:

Регулярные выражения в ограничениях маршрута в ASP.NET Core и Visual Basic .NET
Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850