.NetCore 2.x使用{* catchAll}路由URL。动作始终返回null

时间:2018-12-03 07:54:57

标签: c# asp.net-core .net-core asp.net-core-routing

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

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

我遇到的问题是@Url.Action()总是在此路由上返回null

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

3 个答案:

答案 0 :(得分:1)

您必须在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

答案 1 :(得分:0)

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

答案 2 :(得分:0)

玩转之后,我发现了一种“欺骗”的方式,而且还行得通。如果出现 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()