【问题标题】:MVC routing with "optional" routes带有“可选”路由的 MVC 路由
【发布时间】:2013-05-07 21:24:19
【问题描述】:

我对 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}"
);

现在出于某种奇怪的原因,实际上每个请求都被抓住了(不是我想要的,但很接近)。

大家有什么想法吗?

编辑:

我更接近这个...

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

...但是现在它匹配所有带有 2 部分“foo/bar”的 url,而不是像它应该的那样直接通过其他路由,因为没有“foo”控制器。

【问题讨论】:

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


    【解决方案1】:

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

    我希望为所有人找到一个理想的解决方案,但这只是我的场景中的一个理想......

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

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

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

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

    希望它可以帮助其他人。

    【讨论】:

      【解决方案2】:

      也许我不完全理解你的问题,但为什么不走这条路线:

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

      并将其添加到默认路径之前的路由集合中...

      【讨论】:

      • 我想说“这是可能映射到控制器的 url 的格式,但是如果你发现控制器不存在,因为它的名称属于默认路由和 url 的第 1 部分映射到 cms 控制器上的 getpage"
      • 我对这个问题的回答确实解决了这个问题,但它不是一个理想的选择,因为我必须为每个控制器创建一个规则来匹配它们。我希望使用更全球性的东西,一个可以做同样事情的单一规则,这个解决方案与我的基本相同,它不会捕获所有存在的控制器并落在它们不存在的地方。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-05-10
      • 1970-01-01
      • 1970-01-01
      • 2016-04-10
      • 2011-04-08
      • 2011-06-30
      • 2014-12-07
      相关资源
      最近更新 更多