In this article, we will look at the Attribute Routing in ASP.NET Core Apps. We learnt the basics of Routing in the last tutorial. Routing is how ASP.NET Core matches an incoming URL to a controller action.
There are two ways in which you can configure routing in ASP.NET Core.
- Convention based Routing
- Attribute-based Routing
We learnt Convention based Routing in the last tutorial. We will look what is Attribute based routing in this article.
Table of Contents
What is Attribute Routing
The attribute routing uses the attributes defined directly on the controller action to define the routes. Attribute routing gives you more control over the URLs in your web application.
In convention based routing all the routing is configured in the Startup class. In Attribute Routing routing is configured at the controller level.
How to Setup Attribute Routing
The Routes are added using the Route Attribute on the controller Action. The Route Attribute takes three arguments, URL Pattern, name and order.
In the following code, we have added the route attribute on the index action method, passing “Home” as the URL Pattern.
1 2 3 4 5 6 7 8 | public class HomeController: Controller{ [Route("Home")] public string Index(){ return "Hello from Index method of Home Controller"; } } |
In the above example, the /Home URL invokes the index method of the HomeController class. That is because The Route attribute expects the complete route to the action method.
How to Use Attribute Routing
Create a new ASP.NET Core Web API Project Using NET 5 Framework and VS 2019.
Open the startup.cs
and locate the Configure
method. You will find the following code. The UseEndpoints method registers the Endpoint Middleware, which is responsible for invoking the Endpoint.
The MapControllers()
method registers Endpoint for all the attribute routes present in the application.
1 2 3 4 5 6 7 | app.UseEndpoints(endpoints => { endpoints.MapControllers(); }); |
Now, Create a new empty MVC Empty Controller HomeController
. Add the Route(“Home”) attribute to the index action method.
1 2 3 4 5 6 7 8 9 10 11 | public class HomeController : Controller { [Route("Home")] public string Index() { return "Hello from Index method of Home Controller"; } } |
When we call the URL /Home the Index
Action method of the HomeController
is invoked.
URL | Match ? | Parsed As |
---|---|---|
/ | No | |
/Home | Yes | Controller=Home Action=Index |
/Home/Index | No |
Now change the URL Pattern to “Home/Index”.
1 2 3 4 5 6 | [Route("Home/Index")] public string Index() { return "Hello from Index method of Home Controller"; } |
URL | Match ? | Parsed As |
---|---|---|
/ | No | |
/Home | No | |
/Home/Index | Yes | Controller=Home Action=Index |
Changing the Name of the Action Method
The Very important to note that the URL Pattern does not need to match the Controller and Action Name.
For Example
1 2 3 4 5 6 | [Route("Say/Hello")] public string Index(){ return "Hello from Index method of Home Controller"; } |
URL | Match ? | Parsed As |
---|---|---|
/ | No | |
/Home | No | |
/Home/Index | No | |
/Say/Hello | Yes | Controller=Home Action=Index |
Multiple Routes
You can also set multiple routes to a single action using Attribute Routing as shown below
1 2 3 4 5 6 7 8 | [Route("")] [Route("Home")] [Route("Home/Index")] public string Index(){ return "Hello from Index method of Home Controller"; } |
URL | Match ? | Parsed As |
---|---|---|
/ | Yes | Controller=Home Action=Index |
/Home | Yes | Controller=Home Action=Index |
/Home/Index | Yes | Controller=Home Action=Index |
/Say/Hello | No |
Token Replacement
The Attribute Routing makes it easier for us by providing the tokens for [area], [controller], and [action].
These tokens get replaced by their actual values in the Routes collection
1 2 3 4 5 6 7 8 | [Route("")] [Route("[controller]")] [Route("[controller]/[action]")] public string Index() { return "Hello from Index method of Home Controller"; } |
The tokens in the URL Pattern ensures that the Controller and Action names stay sync with the name of the controller class.
Parameters to Action Methods
Just like in Convention based Routing, We can define additional URL Parameter placing them inside curly braces. This can be passed as parameters to the action method.
1 2 3 4 5 6 7 8 9 10 11 12 | [Route("")] [Route("[controller]")] [Route("[controller]/[action]/{id?}")] public string Index(string id) { if (id !=null) { return "Received " + id.ToString(); } else { return "Received nothing"; } } |
In the above example, id is an Optional parameter. Any Value Received is injected as a parameter to Index Action method.
Combining Routes
We can specify the route attributes on the Controller class. Any URL pattern defined in the Controller class is prepended to the URL Pattern in the Action method.
1 2 3 4 5 6 7 8 9 | [Route("Home")] public class HomeController : Controller { [Route("Index")] public string Index() { return "Hello from Index method of Home Controller"; } } |
This works fine for the Route Home/Index. If the Pattern begins with a / are considered to be absolute path and do not get combined with the parent URL Pattern
This Following will not work with the URL Home/Index.
1 2 3 4 5 6 7 8 9 | [Route("Home")] public class HomeController : Controller { [Route("/Index")] public string Index() { return "Hello from Index method of Home Controller"; } } |
Mixed Routing
You can use both convention-based routing and attribute routing in the same project. However, if you define attribute routing on an action, then convention based routing cannot be used on that Action.
Action Verbs
Attribute route can also be used with HTTP verb attributes like HttpGet, HttpPost etc.
1 2 3 4 5 6 7 8 | [HttpGet("")] [HttpGet("Home")] [HttpGet("Home/Index")] public string Index() { return "Hello from Index method of Home Controller"; } |
Summary
We looked at How to setup and work with attribute routing in ASP.NET Core Apps. We Register the URL Pattern in the Route Attribute on the controller Action methods.
Thanks – this was very helpful. What about multiple parameters – How would I create an endpoint to the request api/scoInfo?activityId=1&studentId=1×tamp=1527357844844 using attribute routing in the controller?
create a view model
And in controller