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

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

Сопоставление адреса URL или URL matching представляет процесс сопоставления запроса с конечной точкой. Данный процесс основывается на пути запроса и полученных в запросе заголовках. Данный процесс проходит ряд этапов:

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

var builder = WebApplication.CreateBuilder();

var app = builder.Build();

app.Map("/hello", () => "Hello METANIT.COM");
app.Map("/{message}", (string message) => $"Message: {message}");

app.Map("/", () => "Index Page");

app.Run();

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

URL matching in ASP.NET Core и C#

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

var builder = WebApplication.CreateBuilder();
var app = builder.Build();

app.Map("/{message?}", (string? message) => $"Message: {message}");
app.Map("/", () => "Index Page");

app.Run();

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

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

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

var builder = WebApplication.CreateBuilder();
var app = builder.Build();

app.Map("/{controller}/Index/5", (string controller) => $"Controller: {controller}");
app.Map("/Home/{action}/{id}", (string action) => $"Action: {action}");

app.Run();

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

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