.NET 5 Универсальный маршрут AspNetCore заменяет определенный маршрут

При переходе с .NET Core 3.1 на .NET 5 мы столкнулись со странным поведением при настройке универсального маршрута.

Соответствующая часть начальной конфигурации выглядит следующим образом:

public void ConfigureServices(IServiceCollection services)
{
    services.AddControllers();
}

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    app.UseStaticFiles();
    app.UseRouting();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapControllerRoute(
                 name: "default",
                 pattern: "home",
                 defaults: new { controller = "Home", action = "Index" });

        //catch-all endpoint
        endpoints.Map("{*.}", async (t) =>
        {
            System.Console.WriteLine("hello");

            await Task.CompletedTask;
        });
    });
}

При вызове URL-адреса: https://localhost:port/home используется универсальный маршрут вместо домашнего контроллера. . Если универсальная карта конечной точки закомментирована, то попадет в конечную точку домашнего контроллера — чего и следовало ожидать в обоих случаях, читая документы MSDN. Поведением до миграции был самый конкретный маршрут, вызываемый первым (т. е. конечная точка домашнего контроллера), и универсальный ответ реагировал только тогда, когда ни один маршрут не мог быть сопоставлен.

Были ли критические изменения в .NET 5 или мы что-то упустили?


person JasonX    schedule 21.01.2021    source источник
comment
Почему вы определяете свои маршруты именно так, а не используете атрибут Route на контроллерах?   -  person Captain Kenpachi    schedule 22.01.2021
comment
Это упрощенный воспроизводимый пример вопроса: почему универсальный маршрут имеет приоритет над определенным маршрутом? На самом деле это часть крупномасштабного распределенного приложения, где большая часть кода зависит от динамической маршрутизации, которая, конечно же, не работает из-за этого. Я хочу знать, является ли это ожидаемым поведением, и если да, то можно ли его переопределить?   -  person JasonX    schedule 22.01.2021
comment
После обхода источника .NET 5 под руководством третьей стороны выяснилось, что алгоритм назначения приоритета неисправен — изначально он назначает приоритет домашнего маршрута 0 и приоритет универсального маршрута 5 из-за жестко запрограммированного универсального, если утверждение. Затем он сортирует маршруты по приоритету и присваивает баллы, присваивая домашнему маршруту балл 1, а комплексному маршруту — 0. Наконец, он сортирует баллы от низшего к более высокому, давая универсальному маршруту окончательный приоритет над чем-либо еще. Может кто-нибудь еще, пожалуйста, подтвердите, что это ошибка?   -  person JasonX    schedule 22.01.2021


Ответы (2)


  1. Вы можете использовать приоритет для устранения несоответствия. Этот маршрут может получить любой URL-адрес, который не был обработан каким-либо другим маршрутом.

    [Route("{*url}", Order = 999)]
    public IActionResult CatchAll()
    {
    
       return View();
    }
    
  2. В этой ситуации другим методом является использование кодовых страниц состояния.

    При запуске

             app.UseExceptionHandler(option=>
             {
                 app.UseStatusCodePagesWithReExecute("/error/{0}");
             });
    

    Контроллер

     [Route("error/404")]
     public IActionResult Error404()
     {
         return View();
     }
    
person Karney.    schedule 22.01.2021
comment
Извините, @Karney, ваш ответ не ответил на мой вопрос. Смотрите принятый ответ для более подробной информации. - person JasonX; 26.01.2021

Как оказалось, такое поведение было связано с тем, что команда aspnetcore внесла изменение в механизм маршрутизации в 5.0 — проблематичное поведение на самом деле является преднамеренным.

Подробнее см. здесь: https://github.com/dotnet/aspnetcore/issues/29594

person JasonX    schedule 26.01.2021