0

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

Q1

文档特别指出“可以很容易”为API版本,而不是“使得它更容易”或“优选”。

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

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

对于那些使用内置的MapRoute方法可能“难以支持”的约定,您可以使用自己的扩展方法扩展基于约定的路由,甚至可以继承类来定义它们。

Q2

订购与属性的路由问题。事实上,属性路由使得查看你的路由注册的顺序变得更加困难。并不是所有的路由都是顺序敏感的,因此它在很大程度上不是问题。

但是,当您的确实与属性路由有顺序问题时,它比使用基于约定的路由时要微妙得多。当反射检索它们时,属性do not guarantee any order。因此,无论您在控制器操作中指定它们的顺序如何,默认顺序都是未知的。

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

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

Q3

我不能给的,你可以使用属性的路由,你不能使用基于约定的路由的具体例子(据我所知,没有一个)。以属性路由不支持的方式使用基于约定的路由的一个示例是制作data-driven CMS routes

属性路由支持基于约定的路由支持的功能的子集。它在技术上并不比基于会议的路由更高级。基于会话的路由选择使您能够直接指定自己的RouteBase(或Route)子类,从而允许您执行许多无法使用内置属性路由的事情,例如基于子域的make路由,查询字符串值,表单后值或Cookie。您甚至可以在高级场景中制作扩展方法。

属性路由无法通过反射进行扩展,因为它使用的许多类型都标记为内部。

但也有可能会考虑使用属性,而不是路由以公约为基础的路由,这取决于你的项目3个令人信服的理由:

  1. 它把路线的背景下,与控制器代码的其余部分,这可能会更容易维护。
  2. 这意味着您不需要在每个路由定义中键入(或复制并粘贴)控制器和操作名称。在维护性方面,在路由和控制器之间维护这种关系(并且解决它的错误)可能花费比在一个地方定义所有路由更值得的成本。
  3. 属性路由是比基于约定的路由更容易学习。如果您的期限很紧张和/或您的团队对路由没有经验,那么使用属性路由可能是一个更好的选择,因为学习曲线更短。

需要从这件事中拿掉的东西是:使用最容易在项目中维护的路由类型。如果您有很多类似的模式,请使用基于约定的路由。如果您的URL在整个项目中不一致或不一致,或者您只是希望在工作时看到与您的操作方法相同的上下文中的URL,请考虑属性路由,但请记住,基于约定的路由是另一种选择。

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