.NetCore 2.x 关于使用 {*catchAll} 路由 URL.Action 总是 returns null

.NetCore 2.x on using {*catchAll} routing URL.Action always returns null

我正在使用这条路线来映射所有未找到的路线:

routes.MapRoute(
    name: "NotFound",
    template: "{*url}",
    defaults: new { controller = "Home", action = "NotFound" }
);

我遇到的问题是@Url.Action()总是returnsnull这条路线

有人可以解释为什么会发生这种情况以及有什么替代方法吗?

我想你调用 @Url.Action() 使用 路由参数 (例如 controller = "Home", action = "NotFound")或使用 路由名称 - 这没有区别 - 为您的 not found 页面生成一个 URL。好吧,你说 URL 可以是影响 入站路由 的任何东西,这很好。但是,当您尝试从路由(出站路由)生成 URL 时,该路由没有任何模板来生成 URL。从路由的角度来看,它可以是任何 URL。所以,null 也是任何 URL。因此,null 将被返回。

你必须在 app.UseMvc(...[Routing] ... 之前添加下面的代码,确保你以正确的顺序使用它,因为顺序真的很重要,管道在 asp.net 核心是倒序的,这意味着如果你在 B 之前添加 A,那么 B 将在 A 之前被调用,你可以在这里阅读更多内容:https://docs.microsoft.com/en-us/aspnet/core/fundamentals/middleware/?view=aspnetcore-2.1#order

app.UseStatusCodePagesWithReExecute("/error/{0}");

并且在控制器中考虑包含不同错误代码的 ErrorController,这里我们只考虑 ErrorController 中的 404 和 500 错误,我们必须为每个错误代码(404、500、未知)提供相应的视图

 public class ErrorController : ControllerBase
    {
        [Route("error/{code:int}")]
        public ActionResult Error(int code)
        {
            switch (code)
            {
                case 404: return View("404");
                case 500: return View("500");
                default: return View("Unknown");
            }
        }
    }

有关更简洁的描述,请在此处查看 Microsoft 文档:https://docs.microsoft.com/en-us/aspnet/core/fundamentals/error-handling?view=aspnetcore-2.1

经过尝试,我找到了一种 "cheat" 的方法,而且还挺管用的。如果我得到 NotFound 页面然后我重定向回同一页面如果 Url.Action() == null

if(this._urlService.Action() == null) //same urlHelper action, only has default Home page values passed into method
{
    var query = string.Empty;
    if(Request.QueryString.HasValue)
    {
        query = Request.QueryString.Value;
    }
    var path = "/Home/NotFound" + query;
    path = string.Concat("/", this._userIdentity.CurrentLanguage.ToString().ToLower(), path);
    return base.Redirect(path);
 }

可能是因为我使用/{culture}/{Controller}/{Action}作为我的主要路线。创建其他测试项目,我的主要路线是默认 /{Controller}/{Action}NotFound 页面

上找到 Url.Action() 完全没有问题