Custom Route Constraints in ASP.Net MVC 5

This article describes Custom Route Constraints in ASP.Net MVC 5 with parameter constraints by placing a constraint name after the parameter name separated by a colon.

Introduction

Attribute Routing is introduced in MVC 5.0. We can also define parameter constraints by placing a constraint name after the parameter name separated by a colon. There are many builtin routing constraints available. We can also create custom routing constraints.

To create a custom route constraint, we have implemented our class from an IRouteConstraint interface. It is a very simple interface and contains the single method: Match. This method returns a Boolean value. If we return false from this method then the route associated with the constraint would not match the request.

Definition of IRouteConstraint interface

public interface IRouteConstraint
{
    bool Match(HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values, RouteDirection routeDirection);
}

Example of creating custom Route Constraint

In the following example, I created a simple custom route constraint that always returns true. Here the CustomRouteConstraint class implemented from the IRouteConstraint interface.

public class CustomRouteConstraint : IRouteConstraint
{
    public bool Match(HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values, RouteDirection routeDirection)
    {
        return true;
    }
}

Custom Route Constraint with parameter

We can also create a Route constraint with a parameter just like length, max, min and so on route constraint.

In the following example, I created a custom a route constraint with a parameter. It accepts a parameter value as an argument and it compares an input value (input by URL) and parameter value and based on this it returns either true or false.

Example

public class CustomRouteWithParameterConstraint : IRouteConstraint
{

    private readonly string _parameterValue;
     public CustomRouteWithParameterConstraint(string parameteValue)
    {
        _parameterValue = parameteValue;
    } 

    public bool Match(HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values, RouteDirection routeDirection)
    {
        object value;
        if (values.TryGetValue(parameterName, out value) && value != null)
        {
            if (value.ToString() == _parameterValue)
            {
                return true;
            }
        }
        return false;
    }
}

Register Custom Route constraint

Before use a custom route constraint, we need to register it whenever the application starts. Using the following code we can register the custom route constraint in the RegisterRoutes method of the RouteConfig class.

public class RouteConfig
{
    public static void RegisterRoutes(RouteCollection routes)
    {
        routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
        var constraintsResolver = new DefaultInlineConstraintResolver();
        constraintsResolver.ConstraintMap.Add("CustomRoute", typeof(CustomRouteConstraint));
        constraintsResolver.ConstraintMap.Add("CustomRouteWithParameter", typeof(CustomRouteWithParameterConstraint));
        routes.MapMvcAttributeRoutes(constraintsResolver);
    }
}
 
Note: when you add custom route constraint in ConstraintMap dictionary, name of key is same as class name of custom route constraint.

How to use customize a route constraint

A custom route constraint can be also used in the same way as a builtin route constraint is used.

Example

[Route("MvcTest/other/{name:CustomRoute}")]

public ActionResult OtherPage(string name)

{

    return View();

}

 

[Route("Mvctest/{name:CustomRouteWithParameter(test)}")]

public ActionResult Index(string name)

{

       return   View();

}

Use custom Route constraint with Convention-Based Routing

A custom route constraint can also be used with a Convention based routing. The new version MVC has an override version MapRoute method that accepts a constraint as a parameter. Using this method we can pass over a custom constraint.

public static Route MapRoute(this RouteCollection routes, string name, string url, object defaults, object constraints);

Example

routes.MapRoute(name: "newRoute",
        url: "Mvctest/{name}",
        defaults: new { controller = "Home", action = "Index" },
        constraints: new { name = new CustomRouteWithParameterConstrain("test") }
);
routes.MapRoute(name: "newRoute1",
      url: "Mvctest/other/{name}",
      defaults: new { controller = "Home", action = "OtherPage" },
      constraints: new { name = new CustomRouteConstrain() }
);

Summary

Using the preceding described method, we can create a custom route constraint.