DCSIMG
ASP.Net MVC Route Constraints - Guy Burstein's Blog

Guy Burstein's Blog

Developer Evangelist @ Microsoft

News

Guy Burstein The Bu

Disclaimer
Postings are provided 'As Is' with no warranties and confer no rights.

Guy Burstein LinkedIn Profile

TwitterCounter for @bursteg

Links

Articles

Blogs I Read

ASP.Net MVC Route Constraints

ASP.Net MVC Route Constraints

ASP.Net MVC Route Constraints

ASP.Net MVC has a powerful Routing Engine that allows mapping between URL Routes and Controller Actions. The default route that is created with an empty ASP.Net MVC application is:

{controller}/{action}/{id}

But, according to application requirements, other routes can be used, with parameters not necessarily of type string and int, and may require certain constraints to take place.

For example, my previous post about Anatomy of an ASP.Net MVC Application can be found at: http://blogs.microsoft.co.il/blogs/bursteg/archive/2008/12/21/anatomy-of-an-asp-net-mvc-application.aspx, and has a route similar to:

/blogs/{blogName}/archive/{year}/{month}/{day}/{*permalink}

Each one of the parameters can be checked for validity of format, values and if its value exists in the DB.

Defining Routes and Default Values

If we take a look at the Global.asax file in out ASP.Net MVC application, we can see that the default route is defined using the RegisterRoutes method:

routes.MapRoute(
    "Default",                                              
    "{controller}/{action}/{id}",                           
    new { controller = "Home", action = "Index", id = ""
);

The first parameter is the name of the route, and it is important for debugging – in order to know which route matches an input url. The second is the route URL with parameters, and the third parameter is default values for the above parameters.

Notice this short way of defining a dictionary with values. An anonymous type that has properties and values is being passed to the constructor of RouteValueDictionary class and using the following code begin transformed into a dictionary:

public class RouteValueDictionary : ... 
{
  public RouteValueDictionary(object values)
  {
    this._dictionary = new Dictionary<string, object>(StringComparer.OrdinalIgnoreCase);
 
    foreach (PropertyDescriptor descriptor in TypeDescriptor.GetProperties(values))
    {
      object value = descriptor.GetValue(values);
      this._dictionary.Add(descriptor.Name, value);
    }
  }
}

We can see this form of passing a dictionary of values a lot in the ASP.Net MVC code and usage.

Defining Route Constraints

The MapRoute method has an additional overload that takes the route constrains as an object, just like the defalut values above. For example, if we want to make sure that the controller is from a list of values, and the id has an email format, we can use the following constraints:

routes.MapRoute(
    "Default",
    "{controller}/{action}/{id}",
    new { controller = "Home", action = "Index", id = "guyb@microsoft.com" },
    new
    {
      controller = new FromValuesListConstraint("Home", "Account"),
      id = new EmailFormatConstraint()
    }
);

This call assigns two constraints: a FromValuesListConstraint on the controller value, and a EmailFormatConstraint to the id value. Each of those constrains implements the interface IRouteConstraint that has a single method Match that returns true of the value matches the constraint:

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

Implementing a Custom Route Constraint

The ASP.Net URL Routing Engine ships only with a single Route Constraint called HttpMethodConstraint, that validates the Http Method against a list of valid method for an action. This means that this is a place for extensibility and the above 2 samples are custom Route Constraints I created.

public class FromValuesListConstraint : IRouteConstraint
{
  public FromValuesListConstraint(params string[] values)
  {
    this._values = values;
  }
 
  private string[] _values;
 
  public bool Match(HttpContextBase httpContext, 
    Route route, 
    string parameterName, 
    RouteValueDictionary values, 
    RouteDirection routeDirection)
  {
    // Get the value called "parameterName" from the 
    // RouteValueDictionary called "value"
    string value = values[parameterName].ToString();
 
    // Return true is the list of allowed values contains 
    // this value.
    return _values.Contains(value);
  }
}

In order to implement a Custom Route Constraint, you should create a class that inherits from IRouteConstraint, and implement the Match method. In the implementation, get the value from the dictionary by the provided parameter name, and validate id according to your scenario. Don’t forget that you have access to the HttpContext, and you can use the Request, Response and other Http Properties.

Enjoy!

Comments

ASP.NET MVC Archived Buzz, Page 1 said:

Pingback from  ASP.NET MVC Archived Buzz, Page 1

# January 11, 2009 1:03 PM

Enlargement said:

I am amazed with it. It is a good thing for my research. Thanks

# January 18, 2009 7:51 AM

Natural said:

I think you are thinking like sukrat, but I think you should cover the other side of the topic in the post too...

# January 19, 2009 5:44 PM

Wakeextelay said:

Man, that’s great…Thanks for providing such a good info

# June 22, 2009 4:04 PM

intittins said:

Oui, je parlais de Calimerotte, mais par contre, quand je parlais du staff, je ne parlais pas de celui du fdf, mais de celui d’HOL (et en passant, HOL n’existe plus, ceux qui geraient l’asso et le serveur ont disparu dans la brume et les domaines ont expire, ce qui fait que nous les 8 qui etions encore actifs dans le staff (moi, Blackhawk, mamboule, Tristou, Elfix, FandeCRF, vincetreize et trioxx/overtux), sommes tous sur le pave depuis debut fevrier). Cali n’etait pas dans le staff du FDF pendant que j’etais encore la-bas, mais a joint le staff FDF bien apres la grosse vague de departs, et son entree coincidait etrangement avec le fait qu’elle avait cesse de se connecter sur hol.

# June 24, 2009 11:24 PM

TypeBrierne said:

I’m new to the site and just purchased lots of items last night, and still have not received an email with the items. How long does it normally take to get the items? I understood that as soon as I paid everything would be emailed to me. Just wondering……

Thanks

# June 25, 2009 9:04 AM

payday loan canada said:

I found beta.blogs.microsoft.co.il very informative. The article is professionally written and I feel like the author knows the subject very well. beta.blogs.microsoft.co.il keep it that way.

# June 29, 2009 2:10 PM

ASP.NET MVC twitter/myspace URL style routing - BaLs Dev Blog said:

Pingback from  ASP.NET MVC twitter/myspace URL style routing - BaLs Dev Blog

# February 15, 2010 1:47 AM

Using ServiceRoute With Existing MVC Routes | Howard Dierking said:

Pingback from  Using ServiceRoute With Existing MVC Routes | Howard Dierking

# May 16, 2011 10:26 PM
Leave a Comment

(required) 

(required) 

(optional)

(required) 


Enter the numbers above: