liveBook · Manning

Route constraint

As explained in Pro ASP.NET Core 7, Tenth Edition

A route constraint is a rule attached to a route parameter that restricts matching to values satisfying a specified condition.

A route constraint restricts which URL path segments can match an endpoint. Default values, optional segments, and catchall segments broaden matching; constraints narrow it. Put a colon and constraint name after a segment variable, such as `{first:int}`. A request whose value fails the constraint does not match that route. section 13.2.5

Constrain two segments

In Program.cs, map a GET endpoint with `app.MapGet("{first:int}/{second:bool}", async context => { foreach (var kvp in context.Request.RouteValues) await context.Response.WriteAsync($"{kvp.Key}: {kvp.Value}\n"); });`. After restarting ASP.NET Core, `/100/true` matches and exposes both route values. `/apples/oranges` has two segments but matches neither constraint, so the request continues to the terminal middleware. section 13.2.5

Choose constraints for the values an endpoint can handle, then test the boundaries:

  • Use built-in constraints such as `alpha`, `bool`, `int`, `guid`, and numeric types. Constraints for locale-sensitive types match invariant-culture formats, not localized ones. section 13.2.5
  • Stack constraints on one variable: `{first:alpha:length(3)}/{second:bool}` matches `/dog/true`, but not `/dogs/true`. All constraints on a segment must be satisfied. section 13.2.5
  • Use `regex(...)` when a segment must match a specified set of values; the capital endpoint demonstrates this with a country segment. section 13.2.5
Table 13.8 The URL pattern constraints (view table figure)

Constraint

Description

alpha

This constraint matches the letters a to z (and is case-insensitive).

bool

This constraint matches true and false (and is case-insensitive).

datetime

This constraint matches DateTime values, expressed in the nonlocalized invariant culture format.

decimal

This constraint matches decimal values, formatted in the nonlocalized invariant culture.

double

This constraint matches double values, formatted in the nonlocalized invariant culture.

file

This constraint matches segments whose content represents a file name, in the form name.ext. The existence of the file is not validated.

float

This constraint matches float values, formatted in the nonlocalized invariant culture.

guid

This constraint matches GUID values.

int

This constraint matches int values.

length(len)

This constraint matches path segments that have the specified number of characters.

length(min, max)

This constraint matches path segments whose length falls between the lower and upper values specified.

long

This constraint matches long values.

max(val)

This constraint matches path segments that can be parsed to an int value that is less than or equal to the specified value.

maxlength(len)

This constraint matches path segments whose length is equal to or less than the specified value.

min(val)

This constraint matches path segments that can be parsed to an int value that is more than or equal to the specified value.

minlength(len)

This constraint matches path segments whose length is equal to or more than the specified value.

nonfile

This constraint matches segments that do not represent a file name, i.e., values that would not be matched by the file constraint.

range(min, max)

This constraint matches path segments that can be parsed to an int value that falls between the inclusive range specified.

regex(expression)

This constraint applies a regular expression to match path segments.

The built-in constraint table helps select a constraint and check its matching format. section 13.2.5

Constraints also affect route selection: a constrained segment takes precedence over an unconstrained segment variable. They do not guarantee a unique match. With `{number:int}` and `{number:double}`, `/23.5` matches the double route, but `/23` matches both and causes an ambiguous-route exception. Prefer making routes more specific with a literal segment or constraint. If overlap cannot be removed, set endpoint `Order`; the lowest value takes precedence. That workaround requires adding configuration through `RouteEndpointBuilder`. section 13.1.5 section 13.3.2

How Pro ASP.NET Core 7, Tenth Edition covers it

How deep it goes
Shows constraint syntax, combinations, URL tests, and ambiguous-route handling, including an endpoint-order workaround.
Examples
Tests `/100/true` against int and bool constraints, `/dog/true` against combined constraints, and `/23` against overlapping numeric routes.
What it assumes
Builds on URL patterns and segment variables, whose route values are demonstrated before constraints are added.
What you can do after
Operate/configure it with `MapGet` constraints and test URLs for successful matches or ambiguous-route exceptions.
How it connects
Connects URL patterns and route values to routing middleware, route precedence, regular expressions, and ambiguous routes.

Also explained in

Compare how 2 books explain route constraint →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Pro ASP.NET Core 7, Tenth Edition. The section links point to the parts of the book it draws on.