Take the 2-minute tour ×

I just began working on an application with a couple areas (basic grid master / details type system..) I'm looking into taking advantage of the nice routing features in MVC (4 specifically) and I'm "just not getting it" I presume.

Currently the only route defined is the basic one:


which is fine, it works with the areas we have defined, so I'm assuming it must know where the user is and route to the appropriate controller based contextually on the location / area that the user is in.. so far nice..

Now, i'm trying to set up a new route that can handle


and specifically something like:




where "New" is the "New" status and have the Action Signature look like:

public ActionResult List(string statusName)

i was assuming I could just add the new route below the default one identifying "statusName" instead of Id, but of course, how the H would the routing mechanism know the difference between :



I did try adding a "static" route in the form of

            new { statusName = UrlParameter.Optional }

I thought I could "hiJack" just that one route and do something special with it, but to know avail, the router stops at first match?? I'm assuming that was the wrong way to address this issue anyhow..

so now I'm going through the idea of getting to something like:


ex. /OrderManagerList/viewNew

where these routes would basically be "aliases". I had thought that adding the following route would do the trick:

          new {controller="OrderManager", action="List", statusName= UrlParameter.Optional }

with the associated action on the OrderManager controller:

public ActionResult List(string statusName)

no matter what I try, the argument is null, or the "resource cannot be found"

I know the controllers need to have a corresponding View file.. but that's not the issue here, the issue is my attempt at understanding the routing..

SO my questions.. fundamentally, what am I missing about the routing in MVC (4)? even some good articles for a simpleton like myself to understand?

my understanding; define a route, and map it's "endpoint".. however, i think i'm not understanding the assumptions that the machine is making..

anyhow, let me know if further explain / edit is required..

thanks in advance.

share|improve this question
For starters, look at the constraints argument. You can supply constraints: new { statusName = @"^[a-zA-Z]+$" } and make it a word, vs. constraints: new { statusId = @"^\d+$" }. Even still, I would probably look at using a different type of route though instead of relying on constraints. Something like OrderManagerList/ByStatusName/{statusname} vs. OrderManaerList/ByStatusId/{statusId} –  Brad Christie Jan 29 '13 at 1:32
@BradChristie -Thanks for the feedback. I did see some info on Constraints.. i could see that working, but would prefer just getting the routing right.. In this example: OrderManagerList/ByStatusName/{statusname} would I need to define a separate route to handle that? or is that just defining: OrderManagerList(Controller) / ByStatusName (Action) /{statusName}(variable)? i guess i'm not sure how to control where that URL would map to something other than the stringent naming conventions.. Thanks again –  hanzolo Jan 29 '13 at 1:57
Indeed, you could use the generic, but keep the {argument} vague. For example: OrderManage/{action}/{filter} & new { controller = "OrderManage", filter = UrlParameter.Optional } then ActionResult ByStatusName(String filter) & ActionResult ByStatusIs(Int32? filter). –  Brad Christie Jan 29 '13 at 2:23
add comment

1 Answer

up vote 5 down vote accepted

The basic principle of routes is that they are evaluated from the top down, and the routing systems uses the first match, not the best match.

The implication of this is that you must order your routes in order of specificity, with the most specific route first and the most general route last.

With this principle in mind, let’s look at your situation. Initially, you have only the default route defined:


The URL pattern is "{controller}/{action}/{id}". By itself, this would match any three-segment URL, and would not match any URL that had less than three segments. However, the third input parameter is the default parameter, which defines defaults for the first and second segment and indicates that the third segment is optional. The next effect of this is to make the route match URL having 0,1, 2 or 3 segments.

Now you want to add a route where the third URL segment is mapped to a “statusName” parameter, and can handle URLs like:


There are two basic approaches you can take here. You can 1) create a very specific route that will handle these two URLs only, or 2) you can try and create a more general route to handle the general case. Let’s look at the first case first. You can create a route as follows:

routes.MapRoute("", "OrderManager/List/{statusName}",
              new { Controller = "OrderManager", Action = "List" });

Note that because this route is more specific than the default route, you must put this route before the default route.

If you want to have a more general route, you need to decide how this route will differ from the default route, since they both will match URLs having three segments. Let’s say you decide that the new route will accept anything that only contains letters in the third segment, leaving the default route to handle anything containing numbers. You can do this using route constraints. For example you could write a route as follows:

            name: "Default",
            constraints: new { id = @"^\d+$" });

            name: "NewRoute",
            url: "{controller}/{action}/{statusName}",
            defaults: new { Controller = "OrderManager", Action = "List" },
            constraints: new { statusName = "^[A-Za-z]+$" });

With these two routes, any three-segment URL having only letters in the third segment will put the third segment into a variable called “statusName”, whereas any URL with an integer in the third segment will put the third segment into a variable called “id”.

In any applications of real complexity, routes can get complicated, and it is very advantageous to write unit tests for your routes, to insure that you don’t screw things up when you add or modify a route.

For good references on routing, see Scott Sanderson's book or see the MSDN documentation

share|improve this answer
Your explanation was extremely well put and really helped me get my head around it.. This makes a lot more sense to me know. Next: Unit test routes!!! frickin awesome.. Thanks again! –  hanzolo Jan 29 '13 at 17:55
Glad it was helpful. Yeah, unit tests for routes are really cool. You need to set up some helper methods. The Scott Sanderson MVC book has a really good section on how to do this. –  Joe Alfano Jan 29 '13 at 20:51
add comment

Your Answer


