属性与常规路由 [英] Attribute vs Conventional Routing

本文介绍了属性与常规路由的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

第一季度:因此,这文章说,对于api版本控制,属性路由比常规路由更有利.我不清楚这种说法背后的原因,因为对我来说,是为了支持这些观点:

Q1: So this article says attribute routing is more favourable than conventional routing for api versioning. It's not clear to me the reasons behind such claim because to me in order to support these:

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

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

all you need to do is to define two routes:

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

某事可以分享一些见识吗?

Can something share some insight?

第二季度:本文说,常规路由的一个问题是表中条目的顺序,以及您可能会意外地将请求映射到错误的控制器.为什么这不是属性路由的问题?我的意思是模板只是一个字符串,因此如何防止我定义两条路线,一条路线比另一条路线更通用?

Q2: this article says one issue with conventional routing is the order of the entries in the table and that you can accidentally have requests being mapped to the wrong controller. Why is this not an issue with attribute routing? I mean the template is just a string so how can it prevent me from defining two routes where one is more generic than the other?

Q3:有没有人可以举一个具体的示例,说明您可以使用属性路由完成而不能使用常规路由? -我不是在谈论代码的可读性和可维护性.

Q3: Can any give a concret example where you can accomplish with attribute routing but can't with the conventional routing? - I am not talking about code readability and maintainability.

推荐答案

Q1

该文档特别声明了API版本控制的使之变得容易",而不是使之变得容易"或首选".

Q1

The document specifically states "makes it easy" for API versioning, not "makes it easier" or "is preferred".

我不同意基于约定的路由不一定是难以支持的"(前提是您了解路由的工作原理).但是,如果您没有使用项目中多个控制器之间共享的约定,则使用属性路由时要维护的代码要少得多.即,您不必在代码中的每条路由上指定要使用的控制器和动作,因为RouteAttribute知道它与本机配对的动作/控制器.

I don't agree that convention-based routes are necessarily "hard to support" (provided you understand how routing works). But if you are not using a convention that is shared across multiple controllers in your project, it is far less code to maintain if you use attribute routing. Namely, you don't have to specify the controller and action to use on every route in the code since the RouteAttribute knows the action/controller it is paired with natively.

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

But as the document points out, putting all of your routes in one place does also have its merits. If your API is such that you can use conventions that apply to multiple/all controllers, then setting a single convention is easier to maintain than multiple route attributes.

对于内置的MapRoute方法可能难以支持"的约定,您可以根据需要使用自己的扩展方法来扩展基于约定的路由,甚至可以继承RouteBase类来定义它们你喜欢.

For those conventions that might be "hard to support" with the built-in MapRoute method, you can extend convention-based routing as necessary using your own extension methods and even inherit the RouteBase class to define them however you like.

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

Ordering is an issue with attribute routing. In fact, attribute routing makes it more difficult to see what order your routes are registered in. Not all routes are order-sensitive, so it is not an issue much of the time.

但是,当您在属性路由中遇到排序问题时,与使用基于约定的路由相比,它要微妙得多.反射检索属性时,属性不保证任何顺序.因此,无论您在控制器操作中指定了什么顺序,默认顺序都是未知的.

However, when you do have an ordering problem with attribute routing, it is much more subtle than when using convention-based routing. Attributes do not guarantee any order when Reflection retrieves them. Therefore, the default ordering is unknown regardless of what order you have specified them on your controller actions.

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

Fixing ordering on attribute routing can be easy. Simply specify the Order property of the attribute (lower values are evaluated before higher values).

也就是说,没有无法指定不同控制器之间的顺序,因此最终可能会咬你.如果发生这种情况,唯一的内置替代方法就是基于约定的路由.

That said, there is no way to specify order between different controllers, so it could end up biting you. If that happens, the only built-in alternative is convention-based routing.

在无法使用基于约定的路由(以及AFAIK,没有一个)的情况下,我无法给出具体示例.以属性路由不支持的方式使用基于约定的路由的一个示例是制作数据驱动的CMS路由

I can't give a concrete example of where you can use attribute routing where you can't use convention-based routing (and AFAIK, there isn't one). An example of using convention-based routing in a way that is not supported by attribute routing is to make data-driven CMS routes.

属性路由支持基于约定的路由支持的功能的子集.它在技术上没有比基于约定的路由更先进.基于约定的路由使您能够直接指定自己的RouteBase(或Route)子类,这使您可以执行内置属性路由无法完成的许多事情,例如基于在子域中,查询字符串值,表单发布值或Cookie.您甚至可以制作扩展方法,以便在高级方案中根据约定生成路由.

Attribute routing supports a subset of the functionality that convention-based routing supports. It is not more advanced technologically than convention-based routing. Convention-based routing gives you the ability to directly specify your own RouteBase (or Route) subclass, which allows you to do many things that you cannot do with the built-in attribute routing, such as make routes that are based on subdomains, query string values, form post values, or cookies. You can even make extension methods that generate routes based on conventions in advanced scenarios.

不能通过反射来扩展属性路由,因为它使用的许多类型都标记为内部类型.

Attribute routing cannot be extended this way without resorting to Reflection because many of the types it uses are marked internal.

但是有3个令人信服的原因,根据您的项目,您可能会考虑使用属性路由而不是基于约定的路由:

But there are 3 compelling reasons you might consider using attribute routing instead of convention-based routing, depending on your project:

  1. 它将路由与控制器代码的其余部分放在上下文中,这可能使维护变得更容易.
  2. 这意味着您无需在每个路由定义中键入(或复制和粘贴)控制器和动作名称.维护路由和控制器之间的这种关系(并在出现错误时进行处理)可能比在可维护性方面将所有路由定义在一个地方的成本要高.
  3. 与基于约定的路由相比,
  4. 属性路由更容易学习.如果您的截止日期很紧,并且/或者您的团队缺乏路由选择的经验,那么使用属性路由可能是一个更好的选择,因为学习曲线较短.
  1. It puts the routes in the context with the rest of the controller code, which might make it easier to maintain.
  2. It means you don't need to type (or copy and paste) controller and action names into each of your route definitions. Maintaining this relationship (and working out when it is wrong) between routes and your controllers might cost more than what it is worth to have all of your routes defined in one place in terms of maintainability.
  3. Attribute routing is easier to learn than convention-based routing. If your deadline is tight and/or your team is inexperienced with routing it could be a better choice to use attribute routing because the learning curve is shorter.

要摆脱的事情是:使用最容易在项目中维护的路由类型.如果您有许多相似的模式,请使用基于约定的路由.如果您的URL在整个项目中不一致或不规则,或者您只是想在工作时在与操作方法相同的上下文中查看URL,请考虑属性路由,但请记住,基于约定的路由是另一种选择.

The thing to take away from this is: Use the type of routing that will be easiest to maintain in your project. If you have lots of similar patterns, use convention-based routing. If your URLs are inconsistent or irregular across the project or you simply like to see your URLs in the same context as your action methods when you work, consider attribute routing, but keep in mind that convention-based routing is another option.

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

NOTE: Most of the examples I have linked to are for MVC, not Web API. Routing is very similar (in fact, most of the code classes are shared) between the two frameworks. The same concepts can be used in both MVC and Web API as far as attribute/convention-based routing goes, but do be aware that you need to target the System.Web.Http namespace rather than the System.Web.Mvc namespace if you are using Web API and you want to take advantage of those examples.

这篇关于属性与常规路由的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆