分层MVC路由策略

时间:2012-10-16 03:25:29

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

我确信这已在其他地方得到解答,但我似乎无法在任何地方找到明确的帖子。

关于分层路由的大多数帖子都会讨论您何时需要Url中无限数量的令牌。我的问题更多地讨论了当某个实体存在而没有在另一个实体的上下文中关联时没有意义。

例如,我有一个Contract实体以及预期的Contract控制器。它具有标准操作,如索引,编辑,创建等。我的网址看起来像

/Contracts/                   ' list all contracts
/Contracts/Create/            ' display form to create new contract
/Contracts/Edit/87Y5r3/       ' display form to edit contract 87Y5r3

现在假设I Order实体必须与给定的合约相关联。使用(几乎)默认路由我将有Urls of

/Orders/                          ' display all orders across all contracts
/Orders/Index/87Y5r3              ' display all orders for contract 87Y5r3
/Orders/Create/87Y5r3             ' display form to create new order for contract 87Y5r3
/Orders/Edit/87Y5r3/45            ' display form to edit order 45 under contract 87Y5r3

我当然可以在调整它时保留几乎默认的路由,以支持合同号和订单号等附加参数。

或者我可以更改路由以显示Orders位于层次结构中的“合同”下。在我看来,我有几条路要走:

1)拥有一个处理合同和订单的控制器以及用于将操作映射到方法的众多自定义路由。这给了我的网址

/Contracts/                        ' maps to Index action in the Contract controller
/Contracts/Create/                 ' maps to Create action in the Contract controller
/Contracts/Orders/                 ' maps to IndexOrders action in the Contract controller
/Contracts/Orders/Index/87Y5r3     ' maps to IndexOrders action in the Contract controller
/Contracts/Orders/Edit/87Y5r3/45   ' maps to EditOrders action in the Contract controller

虽然我无法想象只有一个控制器的任何好的论据,但我猜这个好处也可以分成一个Contracts控制器和一个带有适当路径的Orders控制器。

要点的主要内容是合同编号即将到达网址的末尾。

2)另一种选择是单独的控制器,但使用以下Urls。这对我来说似乎更自然(逻辑)。

/Contracts/                              ' maps to Index action in the Contract controller
/Contracts/Create/                       ' maps to Create action in the Contract controller
/Contracts/?????/87Y5r3/Orders/Index/    ' maps to Index action in the Order controller
/Contracts/?????/87Y5r3/Orders/Edit/45   ' maps to Edit action in the Order controller
/Contracts/?????/All/Orders/             ' maps to Index action in the Order controller

在这种情况下,合同编号位于Url中的合同标记之后,订单编号即将结束。我已经确定了一些问题/关注点

  • 如何处理所有合同中的订单数据。正如您所看到的那样,使用特殊的“全部”令牌处理它。

  • 我将对Url的“合同”部分采取什么操作。默认情况下,Mvc中的路由是/ {controller} / {action} / {id}。

3)我见过的第三个选项(但是对于评估优缺点不够了解)是使用RESTful API。我相信这会(可能)解决我在使用订单时对合同使用什么行动的第二个担忧。基本思想是将动作替换为像DELETE或PUT这样的HTTP动词,它只需要应用于Url末尾的实体。

在这种情况下,我最终会得到像

这样的东西

GET / Contracts /'映射到合同控制器中的索引操作 POST / Contracts / Create /'maps to在Contract控制器中创建操作 GET / Contracts / 87Y5r3 / Orders /'映射到订单控制器中的索引操作 PUT / Contracts / 87Y5r3 / Orders / 45'映射到Order控制器中的Edit操作 GET / Contracts / All / Orders /'映射到订单控制器中的索引操作

虽然RESTful可能是要走的路但我绝对不了解它而我最初的反应是它增加了复杂性和限制(有多少动词?)可能会限制它的用处。

根据我的快速阅读,使用RESTful方法(包括下面@Robotsushi建议的ASP.NET Web API)并没有真正回答我的问题。如果我的页面通过AJAX和JSON请求数据,RESTful似乎需要考虑。从这个意义上讲(仅请求数据),它为Urls提供了一种方法。但是,我的问题更侧重于标准MVC模型,其中操作将模型传递给视图。在一天结束时,我仍然需要向我的用户提供网页...

我是否清楚地总结了这一点?我缺少的任何其他策略?这必须是一个相当常见的场景,所以我很惊讶我没有发现大量的文章。

我简化了一些示例,但在我的情况下,我实际上需要将其提升到第三级---合同/订单/项目。

由于

1 个答案:

答案 0 :(得分:-1)

这纯粹是我的意见

我建议您使用网络服务。如果你不能,你仍然可以使用HTTP POST。发送复杂的数据结构会更容易,而不会使大量非结构化键/值对混乱。

如果您使用此策略,您将能够发送XML或JSON作为您的数据结构,并获得您可能需要的复杂实体表示。

如果您不熟悉基于HTTP的Web服务,请查看ASP.NET Web API

祝你好运

修改 您可以将HTTP POST数据发送到MVC控制器。如果这样做,那么您可以使用复杂的序列化格式(如XML或JSON)来发送数据。这将允许您的实体所需的分层嵌套。

我应该更清楚Web服务。您正在执行的操作类型似乎在Web服务中可能会更好。但是,无论您是否选择使用Web服务,您的mvc控制器都可以使用HTTP POST操作正确表示接受数据。

我希望这会有所帮助。