.NET 5 AspNetCore catch-all 路由取代定义路由
.NET 5 AspNetCore catch-all route supersedes defined route
从 .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 命中了 catch-all 路由而不是家庭控制器。如果 catch-all 端点映射被注释掉,则家庭控制器端点被命中——这是我们在这两种情况下所期望的,阅读 MSDN 文档。迁移前的行为是首先调用最具体的路由(即家庭控制器端点),并且只有在没有匹配到路由时才响应。
.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 中引入了对路由机制的更改 - 有问题的行为实际上是设计使然。
从 .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 命中了 catch-all 路由而不是家庭控制器。如果 catch-all 端点映射被注释掉,则家庭控制器端点被命中——这是我们在这两种情况下所期望的,阅读 MSDN 文档。迁移前的行为是首先调用最具体的路由(即家庭控制器端点),并且只有在没有匹配到路由时才响应。
.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 中引入了对路由机制的更改 - 有问题的行为实际上是设计使然。