Attribute Routing
WEBAPI2 The default routing rules we call based on contract routing, and many times we use RESTful style URIs. Simple routing is no problem, like api/products/{id}, but some things are hard to handle, There are nested relationships between resources: Customers include orders, books have author attributes, and so on. For this URI, we want the route to be like this:/costomers/{customerid}/orders or /costomers/{customerid}/orders/{orderid}
Considering that this is just a routing format for a controller, we have a lot of controllers that are obviously inappropriate with contract-based routing (many routes are configured)
Using attribute routing is simple, adding an attribute to the action
[Route ("customers/{customerid}/orders")] Public Ienumerable<order> getordersbycustomer (int customerId) {...}
By using feature routing, we can also do version control of the API
/api/v1/products
/api/v2/products
Enabling attribute routing requires calling the Maphttpattributeroutes method of the System.Web.HttpConfigurationExtensions class during configuration
using System.Web.Http; namespace webapplication{ public static class Webapiconfig { public static void Register (httpconfiguration config) { // Web API routes CONFIG. Maphttpattributeroutes (); // other Web API configuration not shown.< /span>
In WebApi1, the project template is like this
protected void Application_Start () { webapiconfig.register (globalconfiguration.configuration); // ..... }
If you want to enable attribute routing, you need to change to the following code
protected void Application_Start () { globalconfiguration.configure (webapiconfig.register); // ..... }
Note : Feature Routing and contract-based routing can be used in conjunction with large.
HttpMethod
by default, Webapi finds an action (case insensitive) based on the action's method name prefix, such as getusers, which matches get. by adding the HttpMethod attribute on the action, you can override the HTTP Method that the action needs to map.
The available features include: [Httpdelete],[httppost],[httphead],[httpoptions],[httppatch],[httpget],[httpput]
with the Acceptverbs feature, we can also specify non-standard methods as well as multiple methods, such as [acceptverbs("Mkcol", "GET", "POST")]
Route prefixes
Typically, an action under a controller uses a similar routing template, such as
- [Route ("Api/books")]
- [Route ("Api/books/{id:int}")]
- [Route ("Api/books/{bookid}/authors")]
The [Routeprefix] feature can be specified for the entire controller to use a common prefix to add [Routeprefix ("/api/books")] to the controller, and the action's routing characteristics will be:
- [Route ("")]
- [Route ("{id:int}")]
- [Route ("{bookid}/authors")]
In addition, parameters can be included in the route prefix, such as [Routeprefix ("Api/{userid}/books")]
Routing Constraints
Routing constraints allow us to limit how template parameters are matched. The general syntax is "{parameter: Constraint type}":
[Route ("users/{id:int}"] public User getuserbyid (int ID) { ... } [Route ("users/{name}"] Public User getuserbyname (string name) {...}
If the parameter int, the first Getuserbyid is selected, otherwise it is getuserbyname. (independent of the order defined by the method)
The following table lists the supported constraints
Constraints |
Introduction |
Example |
Alpha |
Match uppercase or lowercase letters (A-Z, A-Z) |
{X:alpha} |
bool |
|
{X:bool} |
Datetime |
|
{X:datetime} |
Decimal |
|
{X:decimal} |
Double |
|
{x:double} |
Float |
Match a 32-bit floating-point number |
{X:float} |
Guid |
|
{X:guid} |
Int |
|
{X:int} |
Length |
Matches a string with a length within a specified range |
{x:length (6)} {x:length (1,20)} |
Long |
|
{X:long} |
Max |
Matches an integer that specifies the maximum value |
{X:max (10)} |
MaxLength |
MATCH specifies a maximum length string |
{x:maxlength (10)} |
Min |
Matches an integer that specifies the minimum value |
{x:min (10)} |
MinLength |
MATCH specifies a minimum length string |
{x:minlength (10)} |
Range |
Matches an integer that specifies a size interval |
{X:range (10,50)} |
Regex |
Match a regular expression |
{X:regex (^\d{3}-\d{3}-\d{4}$)} |
If you want to specify multiple constraints, you need [Route("users/{id:int:min(1)}")]
to use a colon interval
By implementingIHttpRouteConstraint接口,还可以创建自定义路由约束。(不过一般正则就可以搞定了)
You can also replace the entire Defaultinlineconstraintresolver class by implementing the Iinlineconstraintresolver interface. doing so will replace all of the built-in constraints unless the class implementing iinlineconstraintresolver adds them.
Public classnonzeroconstraint:ihttprouteconstraint{ Public BOOLMatch (httprequestmessage request, Ihttproute route,stringparametername, IDictionary<string,Object>values, httproutedirection routedirection) { Objectvalue; if(values.) TryGetValue (ParameterName, outValue) && Value! =NULL) { LongLongvalue; if(Value is Long) {Longvalue= (Long) value; returnLongvalue! =0; } } return false; }} Public Static classwebapiconfig{ Public Static voidRegister (httpconfiguration config) {varConstraintresolver =NewDefaultinlineconstraintresolver (); CONSTRAINTRESOLVER.CONSTRAINTMAP.ADD ("Nonzero",typeof(Nonzeroconstraint)); Config. Maphttpattributeroutes (Constraintresolver); }}[route ("{Id:nonzero}")] PublicHttpresponsemessage Getnonzero (intID) {...}
Custom Routing Constraints demo
optional URI parameter, default value
You can set the URI parameter to be optional by adding a question mark after the parameter constraint, or you can specify the default value as you would a normal method:
[Route ("api/books/locale/{lcid:int?} " )] public ienumerable<book> getbooksbylocale (int1033) {...}
[Route ("api/books/locale/{lcid:int=1033}")] Public Ienumerable<book> getbooksbylocale (int lcid) {...}
These two are equivalent.
Route name
webapi, each route has a name that generates the link and is placed in the HTTP response. (It should be used for redirection)
For example to a [route Span class= "pun" > ( Span class= "PLN" > name = "Getbookbyid" )]
< span class= "str" >< Span class= "pun" > so other action B can use this when it needs to return a link to this action a
Public httpresponsemessage Post (book book) { var response = Request.createresponse ( httpstatuscode.created); string uri = Url.link ("getbookbyid"new {id = Book . BookId}); New uri (URI); return response;}
Routing Order
By setting properties [Route ("xxx", routeorder=n)] You can specify the lookup order of the routes
[Route ("pending"1)] Public Httpresponsemessage getpending () {...}
But it doesn't make much sense to control it in order, rather than setting a better path to reality and not confusing developers.
Http://www.asp.net/web-api/overview/web-api-routing-and-actions/attribute-routing-in-web-api-2#order
Translation: Http://www.asp.net/web-api/overview/web-api-routing-and-actions/attribute-routing-in-web-api-2
Webapi in-depth learning-feature routing