Route Constraints in ASP.NET Core

The Route Constraints helps us to filter out or restrict the unwanted values from reaching the controller action. It does so by checking the Constraint against the value of the URL Parameter.  For Example, you would want to Route engine to match a particular route only if int value is supplied for an URL parameter.

How Route Constraints Work

There are two ways, by which you can add Constraint to a URL Parameter.

  1. Inline with the URL Parameter
  2. Using the Constraint argument of the MapRoute method.

The Inline Constraints are added to the URL Parameter after the colon : sign. 

Once the Routing Engine Finds a Match for the Incoming URL, It invokes the Route Constraint for each segment of the URL to see if it passes the check. The constraints make a simple yes/no decision about whether or not the value is acceptable.

Route Constraints

Open the Project, which we created in Routing tutorial. Go to the Configure method copy the following code.

Now, Copy the following code to the Index method of the HomeController 

A Request for the /Home/Index/10 will match the route. The 10 will be passed as a parameter to the Index Action and you will see “i got 10” in the browser.

A Request for the /Home/Index/Test will also match the route. The  Router parses the “test” to value 0 and injects it as the parameter to index action and you will see “I got 0” in the browser.

You can stop this from happening by using a Route Constraint on the id URL parameter.

Inline Constraint

Inline Constraints are added after the URL Parameter and separated by a colon : sign. For example, you can ensure only integer values are allowed by using the int constraint.

The int constraint checks to see the value of the Id can be parsed to an integer value. The id segment is optional. Hence, the route will match if the Id is not present, but if the id is present, then it must be an integer value.

with int constraint in place, the Request /Home/Index/Test will not match the route.

Using Constraint method of the MapRoute

The Constraints can also be specified using the constraints argument to the MapRoute method.

To do that you need to import Microsoft.AspNetCore.Routing.Constraints namespace.

We create an instance of an Anonymous type, which contains properties, whose property name are same as the URL Parameters,  on which constraints are applied. These Properties are assigned to the instance of the Constraint class.  

In the above example, we have created an Anonymous class. It has id property, which matches to the id URL Parameter.  The Instance of IntRouteConstraint is assigned to the id Property

Constraints in Attribute Routing

You can achieve the same using Attribute routing as follows

Where to Use Constraints

The Constraints can be used for input validation, but that is not the reason they exist.

The Input validations must not be handled by the Route Constraints. Instead, the Controller should validate the Input and send the appropriate error message to the end user. If you use Route Constraints for Input Validations, the client will get a 404 (Not Found) error message. 

The Route constraints should be used to help the Routing Engine to distinguish between two similar looking routes. For Example, consider the following Route

We have two similar looking Routes. post/{id:int} & post/{id:alpha}. With the int & alpha (Accepts only alphabets) constraints in place, we are able to tell the Routing Engine to choose PostsByID Action method for integers and PostByPostName for string values.

List of Route Constraints

The Microsoft.AspNetCore.Routing.Constraints namespace defines a set of classes that can be used to define individual constraints.

Constraints for Checking Data Type 

The following Constrains checks the data type.

constraintInlineClassNotes
int{id:int}IntRouteConstraintConstrains a route parameter to represent only 32-bit integer values
alpha{id:alpha}AlphaRouteConstraintConstrains a route parameter to contain only lowercase or uppercase letters A through Z in the English alphabet.
bool{id:bool}BoolRouteConstraintConstrains a route parameter to represent only Boolean values.
datetime{id:datetime}DateTimeRouteConstraintConstrains a route parameter to represent only DateTime values.
decimal{id:decimal}DecimalRouteConstraintConstrains a route parameter to represent only decimal values.
double{id:double}DoubleRouteConstraintConstrains a route parameter to represent only 64-bit floating-point values
float{id:float}FloatRouteConstraintMatches a valid float value (in the invariant culture - see warning)
guid{id:guid}GuidRouteConstraintMatches a valid Guid value

Constraints for Checking Data Value/Range/Length

The following Constrains checks the Value/Range/Length etc.

constraintInlineClassNotes
length(length){id:length(12)}LengthRouteConstraintConstrains a route parameter to be a string of a given length or within a given range of lengths.
maxlength(value){id:maxlength(8)}MaxLengthRouteConstraintConstrains a route parameter to be a string with a maximum length.
minlength(value){id:minlength(4)}MinLengthRouteConstraintConstrains a route parameter to be a string with a maximum length.
range(min,max){id:range(18,120)}RangeRouteConstraintConstraints a route parameter to be an integer within a given range of values.
min(value){id:min(18)}MinRouteConstraintConstrains a route parameter to be a long with a minimum value.
max(value){id:max(120)}MaxRouteConstraintConstrains a route parameter to be an integer with a maximum value.

Constraints using a Regular Expression

Using Regular expression or regex as constraint offers more flexibility to limit any input.

constraintInlineClassNotes
regex(expression){ssn:regex(^\\d{{3}}-\\d{{2}}-\\d{{4}}$)}RegexRouteConstraintConstrains a route parameter to match a regular expression.

Example of Regular Express Route Constraint

In the following example, we using regular expression to restrict the Year value to 4 digits

Update the Index method of the HomeController.cs

A request for /Home/Index/2017 will match the above route, but request for /Home/Index/20 will fail

Note that Regular expression tokens must be escaped. For example, \,{,},[,] characters need to be escaped by doubling them to escape the Routing parameter delimiter characters.

Hence, ^\d{4}$ becomes ^\\d{{4}}$ in the above example.

Combing Constraints

Multiple Constraints can be combined using a colon : separator as shown below

or using the Constraints method of the MapRoute.

Summary

The Route Constraints are pretty useful options to disambiguate between similar routes. They help us to restrict the unwanted values from reaching the controller action.

5 thoughts on “Route Constraints in ASP.NET Core”

  1. Can we create multiple MapRoutes with same route name?? When using multiple MapRoutes with same route name means throws ‘An item with the same key has already been added. Key: default’ exception. Kindly check.

  2. Hi, i am learning ASP.NETCORE. In this article, under Inline Constraint – “routes.MapRoute(“default”, “{controller=Home}/{action=Index}/{id:int ?}”);”. Here optional parameter contains space. So it throws an exception. Kindly remove that space.

Leave a Comment

Your email address will not be published.

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Scroll to Top