В чем разница между UseRouting и UseEndpoints в конвейере middleware ASP.NET Core?

«В чем разница между UseRouting и UseEndpoints в конвейере middleware ASP.NET Core?» — вопрос из категории ASP.NET Core, который задают на 25% собеседований C# Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

UseRouting и UseEndpoints — это два отдельных, но тесно связанных middleware в конвейере обработки запроса ASP.NET Core. Они разделяют процесс маршрутизации на две фазы.

app.UseRouting() — это промежуточное ПО для сопоставления маршрутов (route matching).

  • Оно вычисляет, какой контроллер и действие (или минимальный API endpoint) должны обработать входящий HTTP-запрос, на основе его пути и метода.
  • Не выполняет конечную обработку запроса. Его задача — определить маршрут и прикрепить к контексту запроса (HttpContext) метаданные (например, выбранный Endpoint).
  • После UseRouting вы можете использовать middleware, которым нужна информация о маршруте (например, app.UseAuthorization()).

app.UseEndpoints() — это промежуточное ПО для выполнения конечной точки (endpoint execution).

  • Оно принимает решение, сделанное UseRouting, и вызывает соответствующий обработчик (метод контроллера, делегат минимального API, Razor Page и т.д.).
  • Внутри UseEndpoints вы настраиваете сами конечные точки с помощью методов MapGet, MapControllers, MapRazorPages.

Типичная последовательность в Startup.Configure:

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    // ... Другое middleware (например, для обработки ошибок, статических файлов)

    app.UseRouting(); // Фаза 1: Сопоставление маршрута

    app.UseAuthentication(); // Может использовать информацию о маршруте
    app.UseAuthorization();  // Может использовать информацию о маршруте

    app.UseEndpoints(endpoints => // Фаза 2: Выполнение конечной точки
    {
        endpoints.MapControllers(); // Регистрация маршрутов для контроллеров
        endpoints.MapGet("/hello", async context =>
        {
            await context.Response.WriteAsync("Hello World!");
        });
    });
}

Итог: UseRouting — «мы решили, куда идти», UseEndpoints — «мы пошли туда и выполнили код».