В чем разница между UseRouting и UseEndpoints?
Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Разница между UseRouting и UseEndpoints в ASP.NET Core
В ASP.NET Core конвейер обработки HTTP запросов строится с помощью middleware компонентов. Методы UseRouting и UseEndpoints являются критически важными элементами этого конвейера и играют разные, но взаимосвязанные роли. Их правильное использование и понимание последовательности необходимо для корректной маршрутизации и обработки запросов.
Основная функция UseRouting
UseRouting — это middleware, который выполняет маршрутизацию на основе информации о конечных точках (endpoints). Его основная задача:
- Вычисление конечной точки: Найти подходящий обработчик (endpoint) для текущего HTTP запроса, сопоставляя его с шаблоном маршрута (например,
/api/products/{id}). - Добавление информации в контекст: После успешного сопоставления, он записывает выбранную конечную точку в свойство
HttpContext(HttpContext.Features.Get<IEndpointFeature>()).
Ключевой момент: UseRouting не вызывает конечную точку. Он лишь определяет, какой обработчик должен быть вызван позже в конвейере.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
// Другие middleware: обработка ошибок, CORS, аутентификация
app.UseExceptionHandler();
app.UseCors();
// UseRouting вычисляет конечную точку для запроса
app.UseRouting();
// Middleware, которые могут использовать информацию о конечной точке (например, авторизация)
app.UseAuthorization();
// UseEndpoints вызывает вычисленную ранее конечную точку
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
endpoints.MapGet("/hello", async context =>
{
await context.Response.WriteAsync("Hello World!");
});
});
}
Основная функция UseEndpoints
UseEndpoints — это middleware, который регистрирует и вызывает конечные точки. Его основные задачи:
- Регистрация конечных точек: Определяет доступные шаблоны маршрутов и их обработчики (например, контроллеры, минимальные API, Razor Pages, Health Checks).
- Вызов конечной точки: Выполняет делегат конечной точки (деlegate), который был ранее вычислен и сохранен в контексте
UseRouting.
Важно: Если UseRouting не был вызван перед UseEndpoints (или если сопоставление не удалось), UseEndpoints не будет иметь информации для выполнения и запрос не будет обработан.
app.UseEndpoints(endpoints =>
{
// Регистрация контроллеров как конечных точек
endpoints.MapControllers();
// Регистрация конечной точки для минимального API
endpoints.MapGet("/api/users/{id:int}", async context =>
{
var id = context.Request.RouteValues["id"];
// ... обработка запроса
});
// Регистрация Razor Pages
endpoints.MapRazorPages();
});
Сравнительная таблица и ключевые различия
| Критерий | UseRouting | UseEndpoints |
|---|---|---|
| Основная роль | Маршрутизатор: сопоставляет запрос с шаблоном. | Исполнитель: вызывает обработчик вычисленной конечной точки. |
| Регистрация конечных точек | Не регистрирует. | Регистрирует все конечные точки приложения. |
| Вызов конечных точек | Не вызывает. | Вызывает вычисленную конечную точку. |
| Позиция в конвейере | Должен быть размещен до middleware, которым нужна информация о маршруте (например, UseAuthorization). | Должен быть размещен после таких middleware и, как правило, в конце конвейера. |
Типичный и правильный порядок в конвейере
Порядок имеет огромное значение, особенно для middleware, таких как UseAuthorization, которые для проверки политик безопасности должны знать, к какой конечной точке направляется запрос. Поэтому типичный конвейер выглядит так:
public void Configure(IApplicationBuilder app)
{
// 1. Middleware, не зависящие от маршрутизации (CORS, обработка ошибок)
app.UseCors();
app.UseExceptionHandler();
// 2. Маршрутизация: вычисление конечной точки
app.UseRouting();
// 3. Middleware, зависящие от маршрутизации (используют Endpoint)
app.UseAuthentication();
app.UseAuthorization();
// 4. Выполнение вычисленной конечной точки
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
Распространенная ошибка и ее следствие
Размещение UseAuthorization до UseRouting является классической ошибкой.
// НЕПРАВИЛЬНЫЙ ПОРЯДОК
app.UseAuthorization(); // Авторизация не знает, куда идет запрос!
app.UseRouting();
app.UseEndpoints(...);
В этом случае middleware авторизации не сможет получить метаданные конечной точки (например, требования [Authorize]), потому что маршрут еще не вычислен. Это может привести к тому, что защищенные endpoints будут доступны без проверки или проверка будет некорректной.
Объяснение через аналогию
Процесс можно сравнить с поиском адреса и посещением дома:
UseRouting— это карта и навигатор. Он анализирует адрес запроса (/api/products/5) и находит точный дом (конечную точку) в городе (вашем приложении).UseEndpoints— это вы сами, переступающие порог дома. Вы идете к конкретному адресу, найденному навигатором, и выполняете действие внутри (обрабатываете запрос).
Таким образом, UseRouting и UseEndpoints — это два фундаментальных, последовательных шага в архитектуре ASP.NET Core: сначала определение пути обработки запроса, затем его фактическое выполнение. Их четкое разделение позволяет другим компонентам middleware (например, для безопасности) интегрироваться в конвейер именно в момент, когда путь уже известен, но обработка еще не началась, обеспечивая гибкость и корректность работы приложения.