4

我刚开始研究一个有几个领域的应用程序(基本网格主/细节类型系统..)我正在考虑利用 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)

无论我尝试什么,参数都是空的,或者“找不到资源”

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

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

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

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

提前致谢。

4

1 回答 1

10

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

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

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

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

URL 模式是“{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 都会将第三段放入名为“ ID”。

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

有关路由的良好参考,请参阅Scott Sanderson 的书或参阅MSDN 文档

于 2013-01-29T17:40:48.577 回答