【问题标题】:Setting up ASP.Net MVC 4 Routing with custom segment variables使用自定义段变量设置 ASP.Net MVC 4 路由
【发布时间】:2013-01-12 11:21:01
【问题描述】:

我刚开始开发一个有几个领域的应用程序(基本的网格主/细节类型系统..)我正在考虑利用 MVC 中的好路由功能(特别是 4),我“只是没有明白了”我猜。

目前唯一定义的路由是基本路由:

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

这很好,它适用于我们定义的区域,所以我假设它必须知道用户在哪里,并根据用户所在的位置/区域根据上下文路由到适当的控制器......到目前为止不错..

现在,我正在尝试设置一条可以处理的新路线

/someController/someAction/{statusName} 

特别是类似的东西:

/OrderManager/List/New 

/OrderManager/List/Viewed

其中“新”是“新”状态,动作签名如下所示:

public ActionResult List(string statusName)

我假设我可以将新路由添加到标识“statusName”而不是 Id 的默认路由下方,但当然,路由机制如何知道 H 之间的区别:

/controller1/action1/15

/controller2/action2/新

我确实尝试以

的形式添加“静态”路由
routes.MapRoute("Default", 
            "ControllerName/ControllerAction/{statusName}", 
            new { statusName = UrlParameter.Optional }
        );

我以为我可以“hiJack”那条路由并对其做一些特别的事情,但要知道是否有用,路由器会在第一次匹配时停止?无论如何,我假设这是解决此问题的错误方法..

所以现在我正在考虑达到以下目标:

/somecustomroutename/somesortValue

例如。 /OrderManagerList/viewNew

这些路线基本上是“别名”。我原以为添加以下路线可以解决问题:

 routes.MapRoute("Default_List",
          "OrderManagerList/{statusName}",
          new {controller="OrderManager", action="List", statusName= UrlParameter.Optional }
      );

与 OrderManager 控制器上的相关操作:

public ActionResult List(string statusName)

不管我怎么尝试,参数都是null,或者“找不到资源”

我知道控制器需要有一个相应的视图文件..但这不是这里的问题,问题是我试图理解路由..

所以我的问题.. 从根本上说,我对 MVC (4) 中的路由缺少什么?甚至一些像我这样的傻瓜能理解的好文章?

我的理解;定义一条路线,并映射它的“端点”..但是,我认为我不理解机器所做的假设..

无论如何,如果需要进一步解释/编辑,请告诉我..

提前致谢。

【问题讨论】:

  • 对于初学者,请查看 constraints 参数。您可以提供constraints: new { statusName = @"^[a-zA-Z]+$" } 并使其成为一个单词,而不是constraints: new { statusId = @"^\d+$" }。尽管如此,我可能会考虑使用不同类型的路线,而不是依赖约束。类似于OrderManagerList/ByStatusName/{statusname}OrderManaerList/ByStatusId/{statusId}
  • @BradChristie - 感谢您的反馈。我确实看到了一些关于约束的信息。我可以看到它在工作,但更愿意让路由正确。在这个例子中:OrderManagerList/ByStatusName/{statusname} 我需要定义一个单独的路由来处理它吗?还是只是定义:OrderManagerList(Controller) / ByStatusName (Action) /{statusName}(variable)?我想我不确定如何控制该 URL 映射到严格命名约定以外的其他内容。再次感谢
  • 确实,您可以使用泛型,但保持 {argument} 模糊。例如:OrderManage/{action}/{filter} & new { controller = "OrderManage", filter = UrlParameter.Optional } 然后ActionResult ByStatusName(String filter) & ActionResult ByStatusIs(Int32? filter)

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


【解决方案1】:

路由的基本原理是自上而下求值,路由系统使用第一个匹配,而不是最佳匹配。

这意味着您必须按照具体的顺序对路线进行排序,最具体的路线在前,最一般的路线在后。

牢记这个原则,让我们看看你的情况。最初,您只定义了默认路由:

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

网址格式为“{controller}/{action}/{id}”。就其本身而言,这将匹配任何三段 URL,并且不会匹配任何少于三段的 URL。但是,第三个输入参数是默认参数,它定义了第一段和第二段的默认值,并表示第三段是可选的。这样做的下一个效果是使路由匹配 URL 具有 0、1、2 或 3 个段。

现在您要添加一个路由,其中​​第三个 URL 段映射到“statusName”参数,并且可以处理如下 URL:

OrderManager/List/New 
OrderManager/List/Viewed 

您可以在此处采用两种基本方法。您可以 1)创建一个仅处理这两个 URL 的非常具体的路由,或者 2)您可以尝试创建一个更通用的路由来处理一般情况。我们先来看第一种情况。您可以按如下方式创建路由:

routes.MapRoute("", "OrderManager/List/{statusName}",
              new { Controller = "OrderManager", Action = "List" });

注意,因为这个路由比默认路由更具体,所以你必须把这个路由放在默认路由之前。

如果您想要更通用的路由,则需要确定此路由与默认路由的不同之处,因为它们都将匹配具有三个段的 URL。假设您决定新路由将接受第三段中仅包含字母的任何内容,而让默认路由处理包含数字的任何内容。您可以使用路由约束来执行此操作。例如,您可以编写如下路线:

        routes.MapRoute(
            name: "Default",
            url: "{controller}/{action}/{id}",
            defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional },
            constraints: new { id = @"^\d+$" });

        routes.MapRoute(
            name: "NewRoute",
            url: "{controller}/{action}/{statusName}",
            defaults: new { Controller = "OrderManager", Action = "List" },
            constraints: new { statusName = "^[A-Za-z]+$" });

使用这两个路由,任何在第三段中只有字母的三段 URL 都会将第三段放入名为“statusName”的变量中,而在第三段中包含整数的任何 URL 都会将第三段放入一个名为“statusName”的变量中。名为“id”的变量。

在任何真正复杂的应用程序中,路由可能会变得复杂,为您的路由编写单元测试非常有利,以确保您在添加或修改路由时不会搞砸。

有关路由的良好参考,请参阅Scott Sanderson's book 或参阅MSDN documentation

【讨论】:

  • 你的解释非常好,真的帮助我理解它。这对我来说更有意义。下一篇:单元测试路线!!!太棒了..再次感谢!
  • 很高兴它有帮助。是的,路线的单元测试真的很酷。您需要设置一些辅助方法。 Scott Sanderson MVC 书中有一个非常好的部分介绍了如何做到这一点。
猜你喜欢
  • 2015-06-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-04-02
  • 2020-04-15
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多