Back to: ASP.NET Core Web API Tutorials
Route Constraints in ASP.NET Core Web API
In this article, I will discuss Route Constraints in ASP.NET Core Web API Applications with Examples. Please read our previous article discussing Route Prefix in ASP.NET Core Web API Routing. We will also work with the same application we created in our Routing in ASP.NET Core Web API article. As part of this article, we will discuss the following Route Constraints.
- Type: int, double, bool, float, datetime, etc.
- Min: min(number)
- Max: max(number)
- Range: range(10. 15)
- Alpha: alpha
- MinLength: minlength(5)
- MaxLength: maxlength(10)
- Length: length(10)
- Required: required
- Regex: regex(expression)
ASP.NET Core Web API Attribute Routing with Route Constraints
Route constraints in ASP.NET Core Web API are used to restrict the HTTP requests that can match a particular route. They enable the API to ensure that the parameters of a route are of a certain type, range, or pattern, which can be essential for the API’s logic and security. Implementing route constraints effectively can lead to more robust and error-free applications.
The Route Constraints in ASP.NET Core Web API Attribute Routing are nothing but a set of rules that can be applied to routing parameters to restrict how the parameters in the route template are matched. The syntax to use Route Constraints is: {parameter:constraint}
Examples to Understand Route Constraints in ASP.NET Core Web API
Let us understand ASP.NET Core Web API Attribute Routing Route Constraints with Examples. Please modify the Employee Controller class as shown below.
using Microsoft.AspNetCore.Mvc; namespace RoutingInASPNETCoreWebAPI.Controllers { [ApiController] [Route("api/[controller]")] public class EmployeeController : ControllerBase { [Route("{EmployeeId}")] [HttpGet] public string GetEmployeeDetails(int EmployeeId) { return $"Response from GetEmployeeDetails Method, EmployeeId : {EmployeeId}"; } [Route("{EmployeeName}")] [HttpGet] public string GetEmployeeDetails(string EmployeeName) { return $"Response from GetEmployeeDetails Method, EmployeeName : {EmployeeName}"; } } }
With the above changes in place, now run the application and navigate to the URL api/employee/10 and api/employee/smith, and in both cases, you will get the following error.
This is because, when the request comes, the application does not identify which version of the GetEmployeeDetails() method to use. Hence, it gives an Ambiguous Match Exception as two endpoints match the same request. This is the situation where the Route Constraints come into the picture in ASP.NET Core Web API.
How do you use Route Constraint in ASP.NET Core Web API?
What we want to achieve is, if an integer is specified in the URL, like api/employee/10, then we need to execute the GetEmployeeDetails(int EmployeeId) method, which takes an integer parameter. On the other hand, if a string value is specified in the URL like api/employee/smith, we need to execute the GetEmployeeDetails(string EmployeeName) method of the Employee Controller that takes the string as a parameter.
This can be very easily achieved in ASP.NET Core Web API Applications using Route Constraints. We need to use the following syntax to specify the route constraint,
{parameter:constraint}
Type Route Constraint in ASP.NET Core Web API:
We can use the type constraint to specify the parameter type. The different types of type constraints supported in ASP.NET Core Web Application are int, decimal, float, long, double, bool, etc. So, with the type constraint in place, if an integer is specified in the URL, then the GetEmployeeDetails(int EmployeeId) action method is invoked. If a string is specified in the URL, then the GetEmployeeDetails(string EmployeeName) method is invoked.
Example: int type constraint:
If you want any parameter to accept only integer values, then you need to specify the int type constraint. So, let us decorate the GetEmployeeDetails method, which takes an integer parameter with the following Route Attribute.
[Route(“{EmployeeId:int}”)]
Note: We don’t need to specify anything for the string parameter as, by default, all the parameters in the ASP.NET Core Web Application are string only.
Let’s modify the Employee Controller to use the above-discussed int-type Route Constraints as shown below.
using Microsoft.AspNetCore.Mvc; namespace RoutingInASPNETCoreWebAPI.Controllers { [ApiController] [Route("api/[controller]")] public class EmployeeController : ControllerBase { [Route("{EmployeeId:int}")] [HttpGet] public string GetEmployeeDetails(int EmployeeId) { return $"Response from GetEmployeeDetails Method, EmployeeId : {EmployeeId}"; } [Route("{EmployeeName}")] [HttpGet] public string GetEmployeeDetails(string EmployeeName) { return $"Response from GetEmployeeDetails Method, EmployeeName : {EmployeeName}"; } } }
With the above changes in place, now run the application and navigate to api/employee/10 and api/employee/smith URLs, and you should get the following output.
Note: When a request is made, the routing engine parses the URL and matches it against the defined routes and their constraints. If the values in the request URL do not meet the constraints specified for a route, that route will not be matched. Instead, the routing engine will continue to look for another route that matches the request URL.
Min(number) constraint in ASP.NET Core:
If you want to apply some minimum value constraint for any parameter, then you can use the Min constraint. The min constraint takes one parameter, i.e., the minimum value, to be applied to the parameter. For example, suppose you want the GetEmployeeDetails(int EmployeeId) action method to be invoked only if the EmployeeId is a number greater than 1000. In that case, you can use the min(1000) constraint in ASP.NET Core Web API as shown below.
[Route("{EmployeeId:int:min(1000)}")] [HttpGet] public string GetEmployeeDetails(int EmployeeId) { return $"Response from GetEmployeeDetails Method, EmployeeId : {EmployeeId}"; }
Now run the application and navigate to the URL by passing a value greater than 1000, and you should get the following output.
Now, if you pass a value less than 1000, then the other GetEmployeeDetails method, which takes string parameter, is executed as shown in the below image.
This is because the second GetEmployeeDetails method takes a string parameter, and here, it treats the value 405 as a string and executes that method.
Alpha constraint in ASP.NET Core Web API:
If you want any parameter to accept only alphabet (a to z characters) values, then you need to specify the alpha constraint. So, let us decorate the GetEmployeeDetails method, which takes string parameters with the following Route Attribute.
[Route(“{EmployeeName:alpha}”)]
Here, alpha stands for uppercase or lowercase alphabet characters. So, change the GetEmployeeDetails method, which takes the string parameter as shown below.
[Route("{EmployeeName:alpha}")] [HttpGet] public string GetEmployeeDetails(string EmployeeName) { return $"Response from GetEmployeeDetails Method, EmployeeName : {EmployeeName}"; }
With the above changes in place, now run the application and test the following three cases. Case 1: Use only letters, and it should work. Case 2: With alphanumeric, it should not work. Case 3: with an integer value less than 1000, it should not work. All three cases are shown in the image below.
Max(Number) constraint in ASP.NET Core Web API:
You can also specify the max constraint in ASP.NET Core Web API along with the max constraint. The max constraint also takes one parameter to specify the maximum value that can be applied to the parameter. For example, if you do not want the EmployeeId in the URL to be greater than 1000, then you can use the max constraint as shown below.
[Route("{EmployeeId:int:max(1000)}")] [HttpGet] public string GetEmployeeDetails(int EmployeeId) { return $"Response from GetEmployeeDetails Method, EmployeeId : {EmployeeId}"; }
Now save the changes, run the application, and navigate to the URL by passing a value less than 1000, and you should get the following output.
Now, if you pass a value greater than 1000, then you will get the following resource not found 404 error page.
Using both min and max constraints for a single route is also possible. For example, if you want the EmployeeId value in the URL to be between 100 and 1000 inclusive, then we can specify both min and max constraints as shown below.
[Route("{EmployeeId:int:min(100):max(1000)}")] [HttpGet] public string GetEmployeeDetails(int EmployeeId) { return $"Response from GetEmployeeDetails Method, EmployeeId : {EmployeeId}"; }
Now save the changes, run the application, and navigate to the URL by passing a value between 100 and 1000, and you should get the response as expected, as shown in the below image.
Now, if you pass a value greater than 1000 or less than 100, then you will get the following resource not found 404 error page.
Range Constraint in ASP.NET Core:
Instead of using the minimum and maximum constraints to specify the minimum and maximum value, we can also use the Range constraint. The Range method takes two parameters: the first is the minimum value, and the second is the maximum value. Let us rewrite the previous example using the range constraint passing 100 and 1000 as the two parameters shown below.
[Route("{EmployeeId:int:range(100,1000)}")] [HttpGet] public string GetEmployeeDetails(int EmployeeId) { return $"Response from GetEmployeeDetails Method, EmployeeId : {EmployeeId}"; }
With the above changes in place, run the application and navigate to the URL by passing a value between 100 and 1000, and you should get the response as expected, as shown in the below image.
Now, if you pass a value greater than 1000 or less than 100, then you will get the following resource not found 404 error page.
MinLength Route Constraint in ASP.NET Core Web API:
The MinLength constraint is used to specify the minimum length constraint on the string parameter. For example, the GetEmployeeDetails(string EmployeeName) method takes one string parameter, and we want to invoke this method only if the length of the input parameter is greater than 5 characters. We can achieve this very easily by using the minlength constraint, which takes one parameter to specify the minimum length. So, let’s modify the GetEmployeeDetails(string EmployeeName) action method as shown below.
[Route("{EmployeeName:alpha:minlength(5)}")] [HttpGet] public string GetEmployeeDetails(string EmployeeName) { return $"Response from GetEmployeeDetails Method, EmployeeName : {EmployeeName}"; }
With the above changes in place, run the application and pass a string of more than 5 characters, and you should see the following response.
Now, if you pass a string of length less than 5 characters in a URL like an api/employee/ABC, then you will get the resource not found 404 error page, as shown in the image below.
MaxLength Route Constraint in ASP.NET Core Web API:
Just like the minlength constraint, we can also apply the MaxLength constraint to specify the maximum length of the string parameter. For example, the GetEmployeeDetails(string EmployeeName) method takes one string parameter; we want if the length of the input parameter is less than 10 characters, then only invoke the method.
We can achieve the above very easily by using the maxlength constraint, which takes one parameter to specify the maximum length. So, let’s modify the GetEmployeeDetails(string EmployeeName) action method as shown below.
[Route("{EmployeeName:alpha:maxlength(10)}")] [HttpGet] public string GetEmployeeDetails(string EmployeeName) { return $"Response from GetEmployeeDetails Method, EmployeeName : {EmployeeName}"; }
With the above changes in place, now run the application and pass a less than 10 characters string, it should work, and you should get the following response.
Now, if you pass a string greater than 10 characters in a URL like api/employee/pranayakumarrout, then you will get the following resource not found 404 error page.
It is also possible to apply both minlength and maxlength constraints on a single parameter. For example, suppose we want to specify the EmployeeName parameter to a minimum of 5 characters and a maximum of 10 characters. In that case, we can apply both minlength and maxlength constraints, as shown below.
[Route("{EmployeeName:alpha:minlength(5):maxlength(10)}")] [HttpGet] public string GetEmployeeDetails(string EmployeeName) { return $"Response from GetEmployeeDetails Method, EmployeeName : {EmployeeName}"; }
Now run the application and test the same by yourself by passing a string between 5 and 10 characters and a string less than 5 and greater than 10 characters.
Length Route Constraint in ASP.NET Core Web API:
The Length Route Constraint is used to specify a string’s exact length. This constraint takes one parameter, which specifies the length to be applied to the parameter. For example, we want the GetEmployeeDetails(string EmployeeName) method to be invoked only when the EmployeeName is five characters. Then, we can achieve the same very easily by using the length route constraint. So, please modify the GetEmployeeDetails(string EmployeeName) method as shown below.
[Route("{EmployeeName:alpha:length(5)}")] [HttpGet] public string GetEmployeeDetails(string EmployeeName) { return $"Response from GetEmployeeDetails Method, EmployeeName : {EmployeeName}"; }
Save the above changes, run the application, and pass a string with exactly 5 characters in the URL, and you should get the following response.
Now, if you pass a string less than 5, like api/employee/abcd, or a string greater than 5, like api/employee/abcdef, then you will get the resource not found 404 error page.
Regex Route Constraint in ASP.NET Core Web API:
You can also validate the value of a particular variable by using the regex route constraint. The regex takes one parameter; you can specify an expression or pattern to validate. Let us understand this with an example. Modify the GetEmployeeDetails(string EmployeeName) method as shown below. Here, we are adding a simple pattern that will validate that if the string starts with the letter a and is followed by b or c, then this method will be invoked.
[Route("{EmployeeName:regex(a(b|c))}")] [HttpGet] public string GetEmployeeDetails(string EmployeeName) { return $"Response from GetEmployeeDetails Method, EmployeeName : {EmployeeName}"; }
Save the above changes, run the application, and pass the abcd string in the URL, and you should get the following response.
Now, if you pass a string that does not start with a or if it starts with a but not followed by b or c character, then you will get the resource not found 404 error page.
Instead of applying the Route Constraints using the Route Attribute, we can also apply the same to the HTTP methods. For a better understanding, please have a look at the following example.
using Microsoft.AspNetCore.Mvc; namespace RoutingInASPNETCoreWebAPI.Controllers { [ApiController] [Route("api/[controller]")] public class EmployeeController : ControllerBase { [HttpGet("{EmployeeId:int}")] public string GetEmployeeDetails(int EmployeeId) { return $"Response from GetEmployeeDetails Method, EmployeeId : {EmployeeId}"; } [HttpGet("{EmployeeName:alpha:length(5)}")] public string GetEmployeeDetails(string EmployeeName) { return $"Response from GetEmployeeDetails Method, EmployeeName : {EmployeeName}"; } } }
Advantages of Using Route Constraints in ASP.NET Core Web API
- Validation at Routing Level: Route constraints validate requests before they reach the action method, potentially reducing unnecessary processing for invalid requests.
- Improved Security: By ensuring that only requests with appropriately formatted parameters are processed, route constraints can help mitigate certain types of attacks.
- Improved URL Matching: By defining precise criteria for route parameters, constraints help ensure that URLs are routed to the appropriate actions.
In the next article, I will discuss the different Controller Action Method Return Types in ASP.NET Core Web API Applications with Examples. In this article, I try to explain Route Constraints in ASP.NET Core Web API applications with examples. And I hope you enjoy this article.