问题描述
从 .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: http://localhost:port/home 命中了包罗万象的路由而不是 home 控制器。如果所有端点映射被注释掉,家庭控制器端点就会被命中——这是我们在这两种情况下所期望的,阅读 MSDN 文档。迁移前的行为是首先调用的最具体的路由(即家庭控制器端点),只有当没有路由可以匹配时,catch-all 才会响应。
.NET 5 中是否有重大更改,或者我们是否遗漏了什么?
解决方法
-
您可以使用优先级来解决不匹配问题。这个路由可以选择任何其他路由没有处理过的 URL。
[Route("{*url}",Order = 999)] public IActionResult CatchAll() { return View(); }
-
在这种情况下,另一种方法是使用状态代码页。
启动中
app.UseExceptionHandler(option=> { app.UseStatusCodePagesWithReExecute("/error/{0}"); });
控制器
[Route("error/404")] public IActionResult Error404() { return View(); }
事实证明,该行为是由于 aspnetcore 团队在 5.0 中对路由机制进行了更改 - 有问题的行为实际上是设计使然。