Route Constraints in MVC

In this post you will learn how to define ‘Route Constraints’ in MVC Application. Route Constraints allow us to apply a regular expression to a URL segment to restrict whether the route will match the request.

Introduction

As you know every MVC application needs at least one route to define how the application should handle requests. When you create MVC Application you get following route defined inside RouteConfig.cs file.

routes.MapRoute(
    name: "Default",
    url: "{controller}/{action}/{id}",
    defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);

In the above example, there are three URL segments. First segment is considered as Controller (‘Home’ is marked as default controller), second segment is considered as Action (‘Index’ is marked as default action) and third segment is considered as Id (‘Id’ is marked as optional). So, in this case these are valid requests:

http://localhost:55514/Home/Blog/2 (Home ‘Controller’, Blog ‘Action’ and 2 ‘Id’)
http://localhost:55514/Blog/Category/mvc (Blog ‘Controller’, Category ‘Action’ and mvc ‘Id’)
http://localhost:55514/2013/10/learnmvc.html (2013 ‘Controller’, 10 ‘Action’ and learnmvc.html ‘Id’)

Sometimes you need more control on URLs, look at the last URL. If you are not careful system will assume 2013 as Controller (2013Controller.cs) and a method called 10. However, just by looking at URL you can tell they should map to different things.

Why Route Constraints? Let’s study a problem.

Assume I want to route following requests that ends with only .html extension to ‘Home’ controller and ‘Blog’ action and also make sure first segment of the URL should be a valid four digit number (like a year) and second segment of the URL should be a valid 2 digit number (like month).


Solution

This is where ‘Route Constraints’ are useful. Constraints allow us to apply a regular expression to a URL segment to restrict whether the route will match the request.

Here is what we need to use:

routes.MapRoute(
    name: "MyCustomRoute",
    url: "{year}/{month}/{pagename}",
    defaults: new { controller = "Home", action = "Blog" },
    constraints: new { year = @"\d{4}", month = @"\d{2}", pagename = @".*?$(?<=\.html)" }
);

Remember to put new route definition before the default simple route because routes are evaluated in order.

In above route definition, URL has three segments {year}, {month} and {pagename}. And for each segments I have defined constraints. For ‘year’ I have used \d{4} which is nothing but a normal regular expression that will allow any four digits number similarly for ‘month’ I have used \d{2} which is also a normal regular expression that will allow any two digits number. And for ‘pagename’ segment I have used .*?$(?<=\.html), a regular expression which will allow all the URLs ends with .html extension. Also notice I have used ‘Home’ as a default controller and ‘Blog’ as default action.

Few RegEx for you

Do not accept URLs ends with .aspx, accepts query string:-
.*?$(?<!\.aspx)

Do not accept URLs ends with .aspx and .php, accepts query strings:-
.*?$(?<!\.aspx|.php)

Only accept urls ends with .html and .aspx, accepts query strings:-
.*?$(?<=\.html|.aspx)


So, in this case following URLs are not valid: because they are not ending with

http://localhost:55514/2013/10/learnmvc.aspx - Not ending with .html extension
http://localhost:55514/2013/9/learn-asp.html - Not a valid two digit month

Pretty easy to work with route constraints, but sometimes it gets painful when you specify incorrect controller or action. Let’s look at a tool now.

Using Route Debugger Tool

Let me tell you about a tool ‘Route Debugger’ which you can use here. Sometimes a bug in your route can break application because it invokes either an incorrect controller or action. So, do not worry just install this tool in the application and it will make your route debugging easier like never before.

To install this tool, just open Package manage console and type ‘Install-Package RouteDebugger’ and you done.


Once you installed, look at the screenshot and see how it works.


If you do not want Route Debugger, you can turn it off from Web.config.

<add key="RouteDebugger:Enabled" value="true" />

change it to one given below

<add key="RouteDebugger:Enabled" value="false" />

Hope this helps.

Comments

  1. Looking back at the example above:
    http://localhost:55514/2013/10/learnmvc.aspx
    What if I want to redirect the user to the correct route which is http://localhost:55514/2013/10/learnmvc.html?
    How can i do that? Thank you

    ReplyDelete
    Replies
    1. As both URLs matching same route (if constraint not defined) you can use request filtering in controller or you can write your customer filter and redirect the requests on appropriate views.

      Delete

Post a Comment

Popular posts from this blog

Migrating database from ASP.NET Identity to ASP.NET Core Identity

Customize User's Profile in ASP.NET Identity System