[Reprinted] ASP. net mvc Web API routing selection, mvcapi
This article describes how ASP. NET Web APIs route Http requests to the controller.
Route table
In ASP. NET Web APIs, controller is a class used to process HTTP requests. The common method used to process HTTP requests is called action method or action. When the Web API framework receives a request, the request is routed to an action for processing.
The ASP. NET Web API framework uses a route table to determine which action method is called. The ASP. NET Web API Project template in Visual Studio creates a default route:
routes.MapHttpRoute( name: "API Default", routeTemplate: "api/{controller}/{id}", defaults: new { id = RouteParameter.Optional });
This default route is defined in the WebApiConfig. cs file under the App_Start directory.
For more information about the WebApiConfig class, see processing ASP. NET Web API.
Each record in the route table contains a routing template. The default Web API routing template is "api/{controller}/{id }". In this template, "api" is a fixed value, while {controller} and {id} are just placeholders (similar to string. the Format string in the Format method uses {0} placeholder ).
When the Web API framework receives an HTTP request, it tries to use the routing template in the route table to match the requested URI. If no template is matched, the client will receive a 404 error. The following Uris match the default template:
- /Api/contacts
- /Api/contacts/1
- /Api/products/gizmo1
However, the URI below does not match because it lacks the "api" section.
/Contacts/1
Note: the fixed amount of "api" is used in routing templates to avoid conflicts with ASP. net mvc routing. In ASP. net mvc, you can use "/contacts" to match a common controller, and use "/api/contacts" to match the controller of the Web API. If you do not like this Convention, you can change the default route table.
Once a matching routing template is found, the Web API selects the appropriate controller and action:
1. Select controller. Web API adds "controller" to the value matching the {Controller} placeholder to find the controller with the same name.
2. Select action. The Web API searches for methods starting with the method of the HTTP request. For example, if there is a Get request, the Web API will look for Methods Starting with Get in the controller, such as "GetContact" or "GetAllContacts ". this Convention applies only to GET, POST, PUT, and DELETE methods. You can enable an HTTP method by adding a feature to the method. We will show this example later.
3. Other placeholders in the routing template, such as {id}, are mapped to the parameter list of the action.
Let's take a look at an example. Suppose there is a controller defined below.
public class ProductsController : ApiController{ public void GetAllProducts() { } public IEnumerable<Product> GetProductById(int id) { } public HttpResponseMessage DeleteProduct(int id){ }}
Below are some possible HTTP requests and the called actions
HTTP Method |
URI Path |
Action |
Parameter |
GET |
Api/products |
GetAllPriducts |
None |
GET |
Api/products/4 |
GetPriductById |
4 |
DELETE |
Api/products/4 |
DeleteProduct |
4 |
POST |
Api/products |
No match |
|
Note that the {id} section in the URI will be mapped to the parameter named id of the action method if it appears. In this example, the controller defines two methods starting with Get, one of which has a parameter named id and the other has no parameters.
Route Variations (I do not know how to translate, routing variation ?)
In addition to naming conventions, you can add HttpGet, HttpPut, HttpPost, or HttpDelete to the action to display the Http method of the specified action response.
In the following example, the FindProduct method corresponds to the Http Get request:
public class ProductsController : ApiController{ [HttpGet] public Product FindProduct(id) {}}
To allow an action to respond to multiple HTTP methods, or to HTTP methods other than GET, PUT, POST, and DELETE methods, you can specify the AcceptVerbs feature for the action, this feature accepts an Http Method list.
public class ProductsController : ApiController{ [AcceptVerbs("GET", "HEAD")] public Product FindProduct(id) { } // WebDAV method [AcceptVerbs("MKCOL")] public void MakeCollection() { }}
Routing by Action Name)
The default routing template uses Http method to select action, but you can also use the action name for routing.
routes.MapHttpRoute( name: "ActionApi", routeTemplate: "api/{controller}/{action}/{id}", defaults: new { id = RouteParameter.Optional });
In this template, the {action} placeholder is the action name in the controller. In this form of routing template, the Http method that the action responds is determined by the features attached to the action. For example, assume that the controller has the following methods:
public class ProductsController : ApiController{ [HttpGet] public string Details(int id);}
In this example, an http get request requesting "api/products/details/1" will be mapped to the Details method. This routing style is similar to ASP. net mvc routing style, and more suitable for RPC-style API (Remote Procedure Call style api ?)
By using the ActionName attribute, we can specify a specific action name without using the action method name. In the following example, two actions will respond to the uri "api/products/thumbnail/id", but they correspond to get method and post method respectively:
public class ProductsController : ApiController{ [HttpGet] [ActionName("Thumbnail")] public HttpResponseMessage GetThumbnailImage(int id); [HttpPost] [ActionName("Thumbnail")] public void AddThumbnailImage(int id);}
Non-action Method
For methods in the controller, we do not want to always respond to HTTP methods. That is to say, the controller can contain non-action methods. In this case, we need to add the NonAction feature to these methods, in this way, the Web Api framework will ignore these methods when performing route matching.
// Not an action method.[NonAction] public string GetPrivateData() { ... }
Http://www.asp.net/web-api/overview/web-api-routing-and-actions/routing-in-aspnet-web-api.