ASP.NET Core Routing Constraints restricts route matching to a set of URLs. This is done by applying different types of constraints or rules in the route patterns.
Let’s start understanding this topic by creating a simple example project.
Page Contents
In your ASP.NET Core MVC 6.0 app add the following route in the Program.cs class.
app.MapControllerRoute(
name: "intConstraint",
pattern: "{controller=Home}/{action=Index}/{id:int}");
If you are using 5.0 version or earlier then enter the below code to the Configure() method of Startup.cs class.
app.UseEndpoints(endpoints =>
{
// Int constraint
endpoints.MapControllerRoute(
name: "intConstraint",
pattern: "{controller=Home}/{action=Index}/{id:int}");
});
I have applied the integer routing constraint on the id parameter. This tells Dot Net to match the URL only when the id parameter in the URL is of type int.
To test how this int constraint works. Add Check action method in the Home Controller of the project:
1 2 3 4 5 | public IActionResult Check( string id) { ViewBag.ValueofId = id ?? "Null Value" ; return View(); } |
The concept of Routing is very vast and I have covered it in 6 tutorials which are:
So make sure to cover each of these one by one.
Now create the Check View inside the Home ➤ Check folder. The Check View code is shown below. This view shows the value of the ViewBag variable which holds the value of the Custom Segment called Id.
<h1>'Home' Controller, 'Check' View</h1>
<h2>Id value is: @ViewBag.ValueofId</h2>
Now request the URL – http://localhost:7004/Home/Check/Hello. We will see a Status Code: 404; Not Found in the browser (image given below).
The reason for this is because the id parameter of the URL should be of int value as we have applied Integer Routing Constraint. But we provided string “Hello” for it in the URL. Therefore the routing engine finds no match and gives 404 error.
Now request the URL – http://localhost:7004/Home/Check/100. This time we provide an int value of 100 for the id parameter and hence the route constraint gets a match.
The view will display – Id value is: 100 as shown in the below image.
In the above route we can also add the question mark (?) after the int to specify that the route also accepts null for the third segment/parameter of the url.
So the below route constraint tells ASP.NET Core to match URLs that have either null (i.e. empty) or int value for the 3rd segment.
1 2 3 | app.MapControllerRoute( name: "intConstraint" , pattern: "{controller=Home}/{action=Index}/{id:int?}" ); |
The Range Constraint applies match only when the int type url segment lies in the specified range.
Consider the below route where I have applied the Range Constraint.
1 2 3 4 5 6 7 | app.UseEndpoints(endpoints => { // Range constraint endpoints.MapControllerRoute( name: "rangeConstraint" , pattern: "{controller=Home}/{action=Index}/{id:range(5,20)?}" ); }); |
So it will match URL like:
/Home/Index
/Admin/List/5
/Home/List/15
/Home/List/20
It won’t match the URLs like:
/Home/Index/3
/Home/Index/Hello
/Home/Index/21
The below table gives some of the important & daily-use Constraints.
Constraint | Description |
---|---|
int | matches int values |
float | matches float values |
decimal | matches decimal values |
datetime | matches datetime values |
double | matches double values |
bool | matches ‘true’ or ‘false’ |
length(len) | matches value with the same number of characters specified by parameter ‘len’ |
length(min,max) | matches values that has length between parameters ‘min’ and ‘max’ (inclusive). |
max(val) | matches int values that are less than val. |
min(val) | matches int values that are more than val |
range(min,max) | matches int values that are between ‘min’ and ‘max’ (inclusive) |
alpha | matches values that have only alphabets (A-Z, a-z) |
regex | matches values defined by regular expression |
The Regex Routing Constraint applies regular expression for matching url. It offers more flexibility than any other constraint as we can create different rules with regular expressions. Consider the below route where I have applied Regex Constraint on the route for the controller parameter.
1 2 3 | app.MapControllerRoute( name: "regexConstraint" , pattern: "{controller:regex(^H.*)=Home}/{action=Index}/{id?}" ); |
This route will match URL’s where the first segment (i.e. controller segment) should start with letter ‘H’.
Let’s take another regex constraint example. Change the route to:
1 2 3 | app.MapControllerRoute( name: "regexConstraint" , pattern: "{controller:regex(^H.*)=Home}/{action:regex(^Index$|^About$)=Index}/{id?}" ); |
In this route I have applied constraint on both controller and action segment of the URL. The controller segment specifies that it should start with letter H.
The action segment specifies that the action segment should be either Index or About. So if we open the URL – https://localhost:7004/Home/Check/100 then it won’t match as the action method is Check. So we will get HTTP Error 404.
So the following URLs will be matched:
/
/Home/Index
/Home/About/
/Home/Index/2
/Home/About/3
The following URL will not match:
Edit/Index/3
/Home/List
We can also combine route constraint together by using the character colon (:). See the below route where I am combining alpha and regex constraints, this means the route will match only when the id segment is either null or it should have both the things which are given below:
1 2 3 | app.MapControllerRoute( name: "combiningConstraint" , pattern: "{controller=Home}/{action=Index}/{id:alpha:regex(^H.*)?}" ); |
The URLs that will match:
/Home/Index/Hello
/Home/Index/Hell
/Home/Index
/Home/Check/HelloJackson
The URLs that will not match:
/Home/Index/100
/Home/About/Jackson
/Home/Check/Hello-Jackson
We can create our own custom route constraints so that the route is matched only when our custom condition is met. Let us build a Custom Routing Constraint to understand it in a better manner.
Example: According to Hinduism there are many Gods like ‘Shiv’, ‘Vishnu’, ‘Ram’, ‘Krishn’, etc. Here I will create a route that matches only when the following 6 Gods name for the value of id segment are present.
1. Ram
2. Shiv
3. Krishn
4. Vishnu
5. Brahma
6. Lakshmi
1 2 3 4 5 6 7 8 9 10 11 12 13 | namespace RouteConstraint.CustomConstraint { public class OnlyGodsConstraint : IRouteConstraint { private string [] gods = new [] { "Ram" , "Shiv" , "Krishn" , "Vishnu" , "Brahma" , "Lakshmi" }; public bool Match(HttpContext httpContext, IRouter route, string routeKey, RouteValueDictionary values, RouteDirection routeDirection) { return gods.Contains(values[routeKey]); } } } |
To create a custom constraint, the class should inherit from IRouteConstraint interface. The IRouteConstraint interface defines a match method and this method decides whether to match the URL or not.
The match method has the following parameters:
In the method I have grabbed the value of the id segment using routeKey object given in the parameter, and then checked if it contains the name of any god.
If there is the name of any god only then the value of true is returned from the method.
The final thing is to apply this constraint on the route so we will need to do some configurations in the Program.cs class as highlighted in the below code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | using RouteConstraint.CustomConstraint; var builder = WebApplication.CreateBuilder(args); // Add services to the container. builder.Services.AddControllersWithViews(); builder.Services.Configure<RouteOptions>(options => options.ConstraintMap.Add( "allowedgods" , typeof (OnlyGodsConstraint))); var app = builder.Build(); // Configure the HTTP request pipeline. if (!app.Environment.IsDevelopment()) { app.UseExceptionHandler( "/Home/Error" ); // The default HSTS value is 30 days. app.UseHsts(); } app.UseHttpsRedirection(); app.UseStaticFiles(); app.UseRouting(); app.UseAuthorization(); app.MapControllerRoute( name: "combiningConstraint" , pattern: "{controller=Home}/{action=Index}/{id:allowedgods}" ); app.Run(); |
Here we have told ASP.NET CORE Routing that we have created a custom constraint and this is added to the route dictionary by the name of allowedgods.
Then finally we have applied this constraint to the id parameter like – {id:allowedgods}. To check it, run the application and go to URL – http://localhost:7004/Home/Check/Shiv. We will see Id value is: Shiv on the browser, as shown by the below image:
Now If we go to the URL – http://localhost:7004/Home/Check/Biden then there will not be a URL match since ‘Biden’ is not a God, and we will get 404 error.
You can download the full codes of this tutorial from the below link:
In this tutorial we learned to use Route Constaints in ASP.NET Core. Download the source codes and run it in your pc, that will help you to get a better understanding of this topic.