Routing and Action Selection in ASP.Net Web API

Introduction

This article is about routing and action selection in the ASP.NET Web API. In this article, you will learn about the Routing phases. And it defines the process of the routing.

First we see the routing phases consisting of the three types:

  • Performs matching between a User Resource Interface (URI) and the route template.
  • Controller selection.
  • Action Selection.

What is the Route template

The one similarity is that the route template is the same as the URI, but one difference is that a route template has a placeholder value. This value is placed within the curly braces:

  api/{controller}/access specifier/Type/{id}

We can also pass the placeholder value at the time of creation of the route.

new { type = "All" }

We can pass the Constraints value that defines to the URI how to perform the matching with the placeholder.

constraints: new { ID = @"" }

There is the matching between the URI path and the template by the framework. Characters of the template should match exactly.

There are two types of placeholders that are used:

  • The first one is the "Controller" that specifies the name of the controller.

  • The second one is "Action" that specifies the name of the action.

If we specify the defaults then the route matches the URI.

  1. public static void Register(HttpConfiguration config)  
  2. {  
  3.     config.Routes.MapHttpRoute(  
  4.         name: "DefaultApi",  
  5.         routeTemplate: "api/{controller}/{type}",  
  6.         defaults: new {type="All" }  
  7.     ); 

Route dictionary

After finding the matches with the URI it generates a dictionary that has the value for every  placeholder. The keys do not include curly braces and act as the name of the placeholder. The values are either default or taken from the URI path. There we use the object of the IHttpRouteData that is used for storing the dictionary.

 

  1. public static void Register(HttpConfiguration config)  
  2. {  
  3.     config.Routes.MapHttpRoute(  
  4.         name: "DefaultApi",  
  5.         routeTemplate: "api/{controller}/{id}",  
  6.         defaults: new { type="All",id = RouteParameter.Optional }  
  7.     );  

 

The preceding example uses "RouteParameter.Optional" if a value is passed for it by the placeholder that is not stored in the route dictionary.

Now for some examples of what the URI path can contain.

  • "http://localhost/api/items" there is items is "controller" and "type" is "all"

  • "http://localhost/api/items/keyboards/1" there is items as "controller", type is keyboards and id is 1.

Selection of the controller

"IHttpControllerSecector.SelectController" is a method that is used to handle the controller. This method uses an object of "HttpRequestMessage".  The "DefaultHttpControllerSelector" class gives the default implementation.

The process proceeds as in the following:

  • The Route dictionary must be checked for the key controller.

  • Finally to retrieve the controller type name the value of this key should be taken and append the string "controller".

  • This type name should be checked for the Web API controller. To implement these steps we use the DefaultControllerSelector that implements the IHttpControllerTypeResolver interface. Now we get the Web API controller type.

Selection of the Action

After selecting the Controller, we use the method "IHttpActionSelector.SelectAction" to select the action. the "ApiControllerActionSelector" class gives the default implementation. The process of selecting an action is as follows.

  • The HTTP method is considered to be a request.

  • The action placeholder is always found in the route template.

  • The controller controls the parameter of the action.

The action selection algorithm is as in the following:

  • Make the list of actions that are the same as the methods of the HTTP request.

  • All the actions that are not the same as the HTTP request must be removed from the dictionary.

  • Action parameters are traced to the URI path:

               Make a list of every action parameter where binding retrieves parameter from the URI, here we do not include the Optional parameter.
               We search the parameters of the list from the URI query string or the Dictionary.
                In this step we select the parameters that are present in the URI path.
                If a match is found more than once then select the parameter with the highest precedence.

  • Avoid the all action that exists in the [NonAction] attribute.

For example:

  1. public void Get(string name)

Here "name" is the parameter that is bound to the URI, the action will only be the same as those URI that have any value for the "name" parameter.