属性与传统路由

时间:2016-07-05 17:00:15

标签: asp.net-web-api asp.net-web-api2 asp.net-mvc-routing asp.net-web-api-routing attributerouting

Q1:所以这个article表示属性路由比api版本化的传统路由更有利。我不清楚这种说法背后的原因是因为我支持这些:

/api/v1/products
/api/v2/products

您需要做的就是定义两条路线:

routes.MapHttpRoute("V1", "api/v1/products",    new {controller = "V1Controller", action = "ListProducts"});
routes.MapHttpRoute("V2", "api/v2/products",    new {controller = "V2Controller", action = "ListProducts"});

某些事情可以分享一些见解吗?

Q2:this article表示传统路由的一个问题是表中条目的顺序,并且您可能会意外地将请求映射到错误的控制器。为什么这不是属性路由的问题?我的意思是模板只是一个字符串,所以它怎么能阻止我定义两个路由,其中​​一个比另一个更通用?

问题3:可以给出一个具体的例子,你可以用属性路由完成但不能用传统路由吗? - 我不是在谈论代码可读性和可维护性。

1 个答案:

答案 0 :(得分:1)

Q1

该文件明确指出API版本“易于使用”,而不是“使其更容易”或“首选”。

我不同意基于会议的路线必然“难以支持”(前提是您了解路由的工作原理)。但是,如果您没有使用项目中多个控制器共享的约定,那么使用属性路由时维护的代码要少得多。也就是说,您不必在代码中的每条路由上指定要使用的控制器和操作,因为RouteAttribute知道它与本机配对的动作/控制器。

但正如文件指出的那样,将所有路线放在一个地方也有其优点。如果您的API可以使用适用于多个/所有控制器的约定,那么设置单个约定比多个路径属性更容易维护。

对于那些内置MapRoute方法可能“难以支持”的约定,您可以根据需要使用自己的扩展方法扩展基于约定的路由,甚至可以继承RouteBase类无论如何都要定义它们。

Q2

订购属性路由的问题。实际上,属性路由使得查看路由的注册顺序变得更加困难。并非所有路由都是对顺序敏感的,因此在很多时候它不是问题。

但是,当有属性路由的排序问题时,它比使用基于约定的路由更加微妙。当Reflection检索它们时,属性do not guarantee any order。因此,无论您在控制器操作中指定了哪种顺序,默认顺序都是未知的。

修复属性路由的排序很容易。只需指定属性的Order属性(在较高值之前评估较低的值)。

那就是no way to specify order between different controllers,所以最终可能会咬你。如果发生这种情况,唯一的内置替代方案是基于约定的路由。

Q3

我不能举一个具体的例子,你可以在哪里使用属性路由,你不能使用基于约定的路由(和AFAIK,没有一个)。以属性路由不支持的方式使用基于约定的路由的示例是data-driven CMS routes

属性路由支持基于约定的路由支持的功能的子集。它在技术上不比基于约定的路由更先进。基于约定的路由使您能够直接指定自己的RouteBase(或Route)子类,这允许您执行许多内置属性路由无法做到的事情,例如make基于子域,查询字符串值,表单发布值或cookie的路由。您甚至可以在高级方案中制作generate routes based on conventions的扩展方法。

如果不使用Reflection,就不能以这种方式扩展属性路由,因为它使用的许多类型都标记为内部。

但是有三个令人信服的理由可以考虑使用属性路由而不是基于约定的路由,具体取决于您的项目:

  1. 它将路由放在上下文中与控制器代码的其余部分,这可能使维护更容易。
  2. 这意味着您无需在每个路径定义中键入(或复制和粘贴)控制器和操作名称。在路由和控制器之间保持这种关系(并在错误时解决)可能比在可维护性方面在一个地方定义所有路由的成本高得多。
  3. 与基于约定的路由相比,属性路由更容易学习。如果您的截止日期紧迫和/或您的团队缺乏路由经验,那么使用属性路由可能是更好的选择,因为学习曲线更短。
  4. 要做的就是:使用最容易在项目中维护的路由类型。如果您有许多类似的模式,请使用基于约定的路由。如果您的URL在整个项目中不一致或不规则,或者您只是想在工作时在与操作方法相同的上下文中查看URL,请考虑属性路由,但请记住,基于约定的路由是另一种选择。

      

    注意:我链接的大部分示例都是针对MVC而非Web API。两个框架之间的路由非常相似(事实上,大多数代码类是共享的)。就基于属性/约定的路由而言,可以在MVC和Web API中使用相同的概念,但是请注意,如果您需要定位System.Web.Http命名空间而不是System.Web.Mvc命名空间正在使用Web API,您希望利用这些示例。