Attribute Routing in ASP.
NET
Core MVC
What is Attribute Routing in [Link] Core MVC?
Attribute Routing gives us more control over the URLs by defining routes
directly at action methods or controllers in our [Link] Core MVC Web
Application.
Because With the help of a Attribute Routing, we can define routes directly
on actions and controllers by decorating them with attributes like [Route],
[HttpGet], [HttpPost], etc.
Defining routes directly on controller actions using attributes like [Route],
[HttpGet], [HttpPost]etc. This makes the routing configuration more explicit
and readable.
Note:
The Convention-Based routing is still fully supported by [Link] Core
MVC.
In fact, we can use both these routing approaches in the same project.
If both Routings are present, then .NET Core overrides conventional
routes. This is because .NET Core gives preference to Attribute Routing
Why do we need Attribute Routing in [Link] Core MVC
Applications?
Let us understand the need for Attribute Routing in the [Link] Core MVC
Web Application with an example.
Step=> 1 Adding Student Model:
First, add a class file named [Link], within the Models folder, and copy and
paste the following code.
namespace [Link]
{
public class Student
{
public int Id { get; set; }
public string? Name { get; set; }
}
}
Step=>2 Modifying Student Controller:
We have already created the Student controller within the Controllers folder. If
not, please right-click on the Controllers folder and add a new [Link] Core
MVC Empty controller named [Link], and then copy and paste
the following code.
Step => 3 Modifying [Link] Class file
i. Configured the MVC Middleware Component and the Convention-Based
Routing , In the Main method of the Program class we have
ii. Now, you can access the three action methods of the Student Controller
using the following URLs, and it will work as expected.
[Link]
[Link]
[Link]
iii. In some scenarios, Convention-Based routing makes it very difficult to
support certain URL patterns. And Attribute routing in the [Link] Core
MVC application can easily achieve those URL patterns.
iv. In our example, if we want the URL Pattern “/student/1/courses” and if
that URL Pattern should be mapped to GetStudentCourses(int
studentID), then this type of URL Pattern is very difficult to create using
convention-based routing in an [Link] Core MVC Application.
v. However, we can easily achieve this type of URL pattern by using
attribute routing in an [Link] Core MVC application.
How Do We Use Attribute Routing in [Link] Core MVC?
Attribute routing allows us to define routes directly on our controller
and action methods using the Route Attributes.
Applying the Route attribute at the Controller level applies to all the
controller’s action methods.
We can also use the [HttpGet], [HttpPost], [HttpPut], [HttpDelete], and
[HttpPatch] Attributes at the action method level to define the Route
Pattern.
Step=> 1 Adding Student Model
First, add a class file named [Link], within the Models folder, and copy and
paste the following code.
namespace [Link]
{
public class Student
{
public int Id { get; set; }
public string? Name { get; set; }
}
}
Step=>2 Modifying Student Controller:
Let us first modify the Student Controller as shown below. So as of now Here,
we have applied the Route Attribute at the Action methods level.
Step => 3 Modifying [Link] Class file
In the [Link] class we have to configure two things compulsory i.e,
1. // Add services to the container.
[Link]();
2. // also use
[Link](); // (optional)
3. // And we need to use one middleware also
[Link](); (compulsoary)
Can we Apply Multiple Route Attributes to a Single Action Method in [Link] Core MVC?
Yes, we can apply Multiple Route Attributes to a Single Action Method in
the [Link] Core MVC Application.
Let us understand this with an example. Please modify the Home Controller
as shown below, and please have a look at the Index Action method, where
we have applied three attribute
If you notice, we have applied the Route attribute three times to the Index()
action method of the Home Controller class.
With each instance of the Route attribute, we specified a different route
template. With the above three Route attributes applied to the Index action
method, we can now access the Index() action method of the
HomeController using the following three URLs.
[Link]
[Link]
[Link]
If we apply the same Route Attributes multiple times with an Action
Method and if we apply the same Route Template to different action
methods, then in both the cases we will get AmbiguousMatchException.
Now run the application and navigate to the above three URLs, and you will
see the Home page as expected.
Attribute Routing with Parameters in [Link] Core MVC Application:
As we already discussed, we can specify the Route Parameters as part of
the route template with Conventional-Based Routing.
We can also do the same thing with Attribute Routing aslo in [Link]
Core. That means we can also define Route Attributes with Route
Parameters.
To understand this, modify the Home Controller as shown below.
As you can see in the above code, the Details() action method has the id
parameter. Notice that in the route template, we also specified the ID
parameter ([Route(“Home/Details/{id}”)]).
So, the URL (/Home/Details/10) will execute the Details(int id) action
method and map the value 10 to the id parameter of the Details action
method. This is done through the model binding process, which will be
discussed in our upcoming articles. Run the application and navigate to
the following URL; you should see the output as expected.
[Link]
Attribute Routing with Optional Parameters in [Link] Core MVC Application
We can also make the Route Parameter optional in Attribute Routing.
by adding a question mark (?) to the route parameter. Moreover we
can also specify the default value by using the parameter = value.
In our example, the Details(int id) action method of the HomeController
is currently executed only if we pass the id parameter value. If we do not
pass the id parameter value, we will get a 404 error.
For example, if we navigate to the following URL, we will get a 404 error.
[Link]
Let us modify the Route attribute of the Details action method as shown
below to make the route parameter id optional by adding “?” at the end,
i.e. [Route(“Home/Details/{id?}”)].
Now run the application and navigate to the following URL. You will see
the output as expected instead of a 404 error.
[Link]
We can also make the parameter optional by specifying a default
value. For a better understanding, please modify the Home Controller
class as follows. Within the Route Attribute of Details action method, we
have specified the default value for the id parameter as 10.
If you run the application and navigate to the URL below without
specifying the ID parameter, it will take the default value 10.
[Link]
Controller and Action Method Names in Attribute Routing
With Attribute Routing in [Link] Core MVC Application, the Controller
and Action Method names do not play any role. To understand this,
modify the Home Controller as shown below.
As you can see, we have specified the Route attribute three times with
the StartPage() action method of the HomeController. So, this StartPage
action method will be executed for the following 3 URLs.
[Link]
[Link]
[Link]
Can we use both Attribute and Convention-Based Routing in a
Single [Link] Core MVC Application?
Yes. Both routing mechanisms can be combined in a single [Link] Core
MVC Web Application.
The controller action methods with the [Route] attribute use Attribute
Routing, and those without the [Route] attribute use Convention-based
routing.
To better understand, please modify the Home Controller class as shown
below.
As you can see in the above code, we have applied the Route Attribute with
the StartPage action method, and we have not applied the Route Attribute
with the Privacy action method. So, in this case, StartPage will use Attribute
Routing, and we can access this method using the following 3 URLs.
[Link]
[Link]
[Link]
On the other hand, the Privacy action method will use Contention-Based
Routing and can be accessed by using the following URL only.
[Link]
Note: It is not possible to access an action method using both Attribute and
Convention Routing.
If Attribute Routing is applied to an action method, then you can access
that method using Attribute Routing only; That means we cannot access
the same Action method using Convention Routing.
Similarly, if Attribute Routing is not applied to an action method, then
you can access that method using Conventional Routing only; you
cannot access the same method using Attribute Routing.
Applying Route Attribute at the Controller Level in the [Link]
Core MVC:
In the [Link] Core MVC Web Application, applying the Route() Attribute to
the Controller class and individual action methods is possible.
If you want to make attribute routing less repetitive, then you need to use
the Route Attribute on the controller level.
Let us understand this with an example. First, modify the Home Controller
class, as shown below. Here, we have created the Home controller with two
action methods.
With the above code in place, we can access the Index() action method
using the following 3 URLs.
/
/Home
/Home/Index
Along the same line, we can access the Details(int? id) action method using
the following 2 URLs.
/Home/Details
/Home/Details/2
If you look at our code, you will see that we are using Route Attributes at
the action method level to define routes.
Further, you will notice that all the routes in the HomeController start with
the same prefix, i.e., Home. That means Home is the common prefix for all
the routes in the Home Controller.
Here, instead of writing the common prefix Home at each action method,
we can specify the Home for the Home Controller (for all its action
methods) using the [Route] attribute at the controller level.
So, modify the Home Controller class as follows. Here, you can see we have
applied [Route] attribute at the controller level. , and we have removed that
Home prefix from each action method Route Attribute.
The Route Attribute we define at the Controller level will be applied to each
action method.
The Route template applied on the controller level is prepended to the
route template applied to the action method level. When you navigate to
the following four URLs,
you will get the output as expected.
[Link]
[Link]
[Link]
[Link]
However, when you navigate to the application’s root URL
([Link] you will get a 404 error. To solve this, you need to
include the route template that begins with “/” i.e. [Route(“/”)] on the
Index() action method, as shown in the image below.
So, modify the Home Controller as follows:
Hence , With the above changes in place, run the application and
navigate to the root URL to see the expected output.
As you can see in the above code, we have applied
the [Route(“Home”)] attribute at the Controller level.
This [Route(“Home”)] attribute eliminates the need to repeat the
common prefix “Home” on each controller action method.
However, sometimes, we may need to override the route attribute
defined at the controller level
How Do We Ignore the Route Attribute Placed at the Controller Level in [Link] Core
MVC?
To ignore the Route Template placed at the Controller level, you must use /
or ~/ at the action method level.
If the action method route template starts with / or ~/, then the controller
Route Attribute will not be combined with the action method route
attribute.
To understand this, let us modify the Home Controller class as shown
below. In the following code, the About action method starts with ~/, so
this action method will not be combined with the controller route attribute.
Now run the application and navigate to /About URL, and you will see the
output as expected.
Defining Route using HTTP Methods:
We can also achieve this using HTTP Verbs. So, let us rewrite the previous
example using HTTP Methods as follows:
What is the Difference Between [Route] and [HttpGet],
[HttpPost], etc., Attributes?
The [Route] attribute specifies a route template for a controller or action
method but does not apply any specific HTTP method.
On the other hand, HTTP method attributes like [HttpGet], [HttpPost],
[HttpPut], and [HttpDelete] not only define the route template but also restrict
that the action method would be invoked only with the specified HTTP
method.