Сопоставление запроса с конечной точкой

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

В основе работы маршрутизации в ASP.NET Core лежит процесс URL matching или составление запрошенного адреса URL с конечной точкой. Данный процесс основывается на пути запроса и полученных в запросе заголовках. Данный процесс проходит ряд этапов:

  1. Сначала выбираются все конечные точки, шаблон маршрута которых совпадает с путем запроса

  2. Далее из полученного на предыдущем этапе набора конечных точек удаляются те, которые не соответствуют ограничениям маршрута

  3. Затем из полученного на предыдущем этапе набора конечных точек удаляются те, которые не удавлетворяют политике объекта MatcherPolicy (вкратце: класс MatcherPolicy позволяет определить порядок сравнения конечных точек и адреса URL)

  4. И в самом конце применяется объект EndpointSelector для выбора из полученного на предыдущем этапе списка конечной точки, которая в конечном счете и будет обрабатывать запрос

Приоритет конечных точек зависит от двух факторов:

  • Порядок следования в наборе конечных точек

  • Приоритетность шаблона маршрута

Приоритетность шаблонов маршрута зависит от специфичности шаблона. Специфичность шаблона определяется на основе следующих критериев:

  • Шаблон маршрута с большим количеством сегментов более специфичен, чем шаблон меньшим количеством сегментов

  • Сегмент с текстовым литералом (статический сегмент) более специфичен, чем сегмент с параметром маршрута

  • Сегмент с параметром, к которому применяется ограничение маршрута, более специфичен, чем сегмент с параметром без ограничения

  • Комплексный сегмент более специфичен, чем сегмент с параметром с ограничением

  • Параметр catch-all (параметр, который соответствует неопределенному количеству сегментов) наименее специфичен

Если в конечном счете осталось две и более конечных точек, которые соответствуют запрошенному адресу, и соответственно система маршрутизации не может выбрать, какая из этих конечных точек должна обрабатывать маршрут, то генерируется исключение.

Например, пусть у нас есть два шаблона маршрута: "/hello" и "/{message}".

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("/hello", Function(context As HttpContext) "Hello METANIT.COM")
        app.Map("/{message}", Function(message As String) $"Message: {message}")
        app.Map("/", Function(context As HttpContext) "Index Page")

        app.Run()
    End Sub
End Module

Оба этих маршрута соответствуют пути запроса "/hello". Однако шаблон маршрута "/{message}" более общий, так как параметр message может передавать какое угодно значение. Тогда как шаблон "/hello" состоит из статического сегмента и соответственно более конкретный, более специфичный, поэтому конечная точка этого шаблона маршрута и будет выбрана для обработки запроса по пути "/hello".

URL matching in ASP.NET Core и Visual Basic .NET

Другой пример:

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("/{message?}", Function(message As String) $"Message: {message}")
        app.Map("/", Function(context As HttpContext) "Index Page")

        app.Run()
    End Sub
End Module

Здесь первый шаблон маршрута применяет необязательный параметр message. Второй шаблон маршрута соответствует корню веб-приложения. И в принципе оба этих шаблона соответствуют пути запроса "/". Однако второй шаблон представляет статический сегмент, поэтому его конечная точка будет выбрана в конечном счете для обработки запроса:

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

Более сложный пример:

Imports Microsoft.AspNetCore.Builder

Module Program
    Sub Main(args As String())

        Dim builder = WebApplication.CreateBuilder(args)
        Dim app = builder.Build()
        app.Map("/{controller}/Index/5", Function (controller As String) $"Controller: {controller}")
        app.Map("/Home/{action}/{id}", Function(action As String) $"Action: {action}")

        app.Run()
    End Sub
End Module

Здесь опять же поскольку во втором маршруте первый сегмент представляет статический сегмент, то именно вторая конечная точка будет выбираться для обработки маршрута:

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