带有"optional"路线

本文关键字:quot 路线 optional 带有 | 更新日期: 2023-09-27 18:13:16

我有点困惑MVC是如何计算出我的路由细节。让我看看我能不能解释清楚。

所以…

routes.MapRoute(
    "Default",
    "{controller}/{action}/{id}",
    new { controller = "CMS", action = "GetPage", id = UrlParameter.Optional }
);

和我的应用程序是一个内容管理系统,所以我想从网站结构创建漂亮的url,所以我将映射一个通配符url,让我确定我是否需要渲染一个404基于什么是在我的数据库…

routes.MapRoute(
    "CMS",
    "{*path}", 
    new { controller = "CMS", action = "GetPage", path = string.Empty } 
);

问题就在这里。

MVC基本上将所有内容与默认路由匹配,因为技术上不需要参数,假设"CMS"控制器上的"GetPage"不需要参数,这不是我想要的。

我想对它说的是"给定2或3个url部分,寻找控制器和动作匹配与可选的id参数,但对于所有其他的url,包括那些你不能匹配到这个路由落在CMS路由"。

我发现唯一"简单"的方法是将第一条路由更改为如下内容…

routes.MapRoute(
    "Default",
    "Get/{controller}/{action}/{id}",
    new { controller = "CMS", action = "GetPage", id = UrlParameter.Optional }
);

那么任何以"Get/"开头的url将匹配该路由,而所有其他路由将自动落在第二条路由上,但这并没有在我的脑海中出现,我也不知道为什么(我认为这是因为它并没有真正解决问题,它只是移动了它)。

我的问题是,我真的不想要一个路由说"给定没有值匹配这个路由",所以我把它改成了这个…

routes.MapRoute(
    "Default",
    "{controller}/{action}/{id}"
);

现在由于一些奇怪的原因,几乎每个请求都击中了catch all(不完全是我想要的,但接近)。

有什么想法吗?

编辑:

我离这个更近了…

    routes.MapRoute(
        "Default", 
        "{controller}/{action}/{id}", 
        new { id = UrlParameter.Optional}
    );

…但是现在它匹配了所有带有两个部分的url "foo/bar"而不是像它应该通过的那样掉到另一个路由,因为没有"foo"控制器

带有"optional"路线

好的,我有一个解决方案,它适用于我,因为99%的请求需要映射到CMS路由,但在你的情况下,它可能不是,如果你有很多控制器,你需要映射到。

我希望找到一个理想的解决方案,但这只是一个理想的在我的场景…

假设你(像我一样)只有一个cms控制器和一个account控制器,你可以这样做:

    routes.MapRoute("Account", "Account/{action}", new { controller = "Account" });
    routes.MapRoute(
        "Default",
        "{*path}", 
        new { controller = "CMS", action = "GetPage", path = string.Empty } 
    );

这样,只有以"Account"开头的url才会被第一条规则捕获,其他所有内容都将落入默认路由并由cms控制器处理。

我计划在添加更多控制器时简单地添加更多路由。这不是一个理想的解决方案,因为从长远来看,这可能意味着我最终会有很多路由映射,但这是一个足够好的解决方案,可以满足我的需求。

希望它能帮助到其他人。

也许我没有完全理解你的问题,但为什么不这样做呢:

routes.MapRoute(
   "CMS",
   "CMS/{action}/{path}", 
   new { action = "GetPage", path = string.Empty } 
);