ASP.NET MVC Controller Attribute Route Precedence

 Author: Shengtao Zhou       Created: 2/15/2019 4:34:13 AM       Modified: 2/7/2020 6:00:23 AM   More...

1. Request Pattern Match

ASP.NET MVC routing is a pattern matching system for mapping browser requests to MVC controller actions.

This is the default route declaration in ASP.Net MVC,
    public class MvcApplication : System.Web.HttpApplication
    {
        public static void RegisterRoutes(RouteCollection routes)
        {
            routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
            routes.MapRoute(
                "Default",              //Name                                
                "{controller}/{action}/{id}",                    //Pattern        
                new { controller = "Home", action = "Index", id = "" }  //Handler
            );
        }
        protected void Application_Start()
        {
            RegisterRoutes(RouteTable.Routes);
        }
    }

Start from MVC 5, attribute routing feature was added. In earlier verison of MVC, you need to use third party routing to achieve this.

Check more details in Attribute Routing in ASP.NET Web API 2.

It decorates a controller action with a [Route] attribute. To enable attribute routing, call MapHttpAttributeRoutes in Register method.

    public static class WebApiConfig
    {
        public static void Register(HttpConfiguration config)
        {
            // Web API routes
            config.MapHttpAttributeRoutes();
            // Other Web API configuration not shown.
        }
    }

A request could match multiple route patterns. The most specific routes have a chance to execute before the more general routes. It only take the first match using the following Precedence.

1) First, check the Order property.


An Order attribute can be added to a route like "Order=1". By default the order is 0. Routes are processed according to an ascending sort of the Order property.

    [Route("posts", RouteOrder = 1)]
    public ActionResult GetData() { 
        ... 
    }

By default, all defined routes have an Order value of 0 and routes are processed from lowest to highest. 

2) Then check Routes without explicit Order attribute as following orders  

a) Literal segments

Hard corded route like this,
    [Route("posts/software")]
    public ActionResult GetData() { ... }

b) Route parameters with constraints, which include parameter place holders
    [Route("posts/{categoryId:int}")]
    public ActionResult GetData() { ... }

c) Route Parameters without constraints
    [Route("posts/{category}")]
    public ActionResult GetData() { ... }

d) Wildcard parameters with constraints. (A wildcard parameter can match multiple parameters)
    [Route("posts/{*categoryId:int}")]
    public ActionResult GetData() { ... }

e) Wildcard parameters without constraints
    [Route("posts/{*categoryId}")]
    public ActionResult GetData() { ... }

3) Routing matching uses case in-sensitive comparison

2. Parameters

Data from web page can be passed to MVC controllers using different ways called model bindings.

1) From Form

Data from web page form using HttpPost can be passed as a class. The name of each input element on web form need to match the attribute names of the parameter class
[HttpPost]
public IActionResult Create(PostEditModel model)
{
...
}
Or,
[HttpPost]
public IActionResult Create([FromForm]PostEditModel model)
{
...
}

2)  From Query String

Data passed as query string like, url?name=abc
[HttpGet]
public IActionResult TestFromQuery(string name)
{
...
}
Or,

[HttpGet]
public IActionResult TestFromQuery([FromQuery]string name)
{
...
}
3) From both form and query string
As below, "name" is from query string, model is from httpPost data.
[HttpPost]
public IActionResult TestFromQuery(string name, PostEditModel model)
{
...
}

3) From Body

Data from HTTP request body
$.ajax({  
url: 'http://url/api/posts',  
type: 'POST',  
dataType: 'json',  
data:{'firstname':'Kate', 'lastname':'White'},  
success: function (data, textStatus, xhr) {  
                ... 
        },  
        error: function (xhr, textStatus, errorThrown) {  
                ... 
    }  
}); 

[HttpPost]  
public String PostAction([FromBody]string firstname, [FromBody] string lastname)  
{  
            ...
}

More...          Back to List          

(Please enter you comments between 100 to 2000 characters. Thanks for your contribution.) 

         Created:       Modified: 

Editing a comment

       (Please enter you comments between 100 to 2000 characters. Please login before edit comment.) 

div class="col-md-2">