【问题标题】:asp.Net MVC 3 Routing Based on Number of Segmentsasp.Net MVC 3 基于段数的路由
【发布时间】:2026-01-26 00:15:02
【问题描述】:

我意识到按特定顺序定义和执行路由的概念,但我定义了以下路由:

routes.MapRoute(
            "Image",                                        
            "Image/{action}/{width}/{height}/{file}",       
            new { controller = "Image", action = "Thumbnail", width = 250, height = 250 }
        );

routes.MapRoute(
           "GetCampaignsByCampaignType",
           "Endorsement/GetCampaignsByCampaignType/{campaignType}",
           new { controller = "Endorsement", action = "GetCampaignsByCampaignType" }
        );

routes.MapRoute(
            "Help",
            "Help",
            new { controller = "Help", action = "Contact" } 
        );

routes.MapRoute(
            "Campaigns",
            "Campaigns",
            new { controller = "Endorsement", action = "Campaigns" } 
        );

routes.MapRoute(
            "Default", // Route name
            "{controller}/{action}/{id}", // URL with parameters
            new { controller = "Home", action = "Index", id = UrlParameter.Optional } 
        );

routes.MapRoute(
            "Campaign",
            "{campaignUrlName}",
            new { controller = "Endorsement", action = "GetCampaign" }
        );

问题与底部 2 条路线有关。我有像 /Summer、/Winter、/Some-other-name 这样的广告系列,我有数百个这样的广告系列,并且不想将它们硬编码进去。我还有其他希望受到打击的路线,例如 /Campaign/Account, /Help/Me/Please(如果有多个片段 /1/2 或 /1/2/3)

什么是正确的顺序或定义,可以让 /1 转到上面定义的最后一条路线,而 /1/2 或 /1/2/3 转到默认的 {controller}/{action}/{id}

目前,这两种情况都使用默认路由 {controller}/{action}/{id},包括 /1。如果我反转它们,那么 /1 可以工作,但 /1/2 或 /1/2/3 不会转到默认路由。

感谢任何帮助。

【问题讨论】:

    标签: asp.net-mvc-3 asp.net-mvc-routing


    【解决方案1】:

    通过正则表达式找到解决方案:

     routes.MapRoute(
                "Default",
                "{controller}/{action}/{id}",
                new { controller = "Home", id = UrlParameter.Optional },
                new { action = @"\w*" }
            );
    
            routes.MapRoute(
                "Campaign",
                "{campaignUrlName}",
                new { controller = "Endorsement", action = "GetCampaign" },
                new { campaignUrlName = @"^([a-zA-Z])[a-zA-Z_-]*[\w_-]*[\S]$|^([a-zA-Z])[0-9_-]*[\S]$|^[a-zA-Z]*[\S]$" }
            );
    

    需要这种方式的操作,默认为两个段 /1/2(完美),并且永远不会捕获任何单个段 url,并且最后一个路由在通过所有其他路由后被命中,并简单地确保它包含正确的字符。

    【讨论】:

      【解决方案2】:

      您的默认路由将始终覆盖您的广告系列路由,因为控制器和方法都有默认值。因此 /Winter 将被解释为具有默认索引(也不存在)的“WinterController”(不存在),因此您将获得 404。

      您必须为 /Winter 和 /Summer 等定义特定的路线。并将它们放在默认值之前。

      【讨论】:

      • 重点是我有成百上千的这些。我不能硬编码这些。一定有更好的方法。将需要找出那是什么。不过谢谢你的回复。只是还不愿意被打败。
      • 好吧,总是有其他方法。您可以编写自己的路由处理程序,在数据库中查找活动,如果找不到,则调用默认路由。
      • 我认为自定义约束是使用正则表达式的方法。只需要弄清楚那是什么。这样就不需要数据库调用了。
      • @gsogoly - 自定义约束对您没有帮助,因为您仍然无法区分广告系列和默认请求。你总是会得到其中一个。拥有两者的唯一方法是进行某种查找以查看有效的广告系列是什么。