0

I had an ASP.Net MVC application with routing configuration rules including this one:

routes.MapRoute(
        "rule1",
    "{controller}/{action}/{cid}/{language}/{itemID}/{uid}",
    new { controller = "Home", action = "action1" }
    , new[] { "MVCApp.Controllers" }
);

I just added new action with same number of parameter and my routing configuration changed like this (rule2 added):

routes.MapRoute(
        "rule2",
    "{controller}/{action}/{cid}/{language}/{phoneNumber}/{uid}",
    new { controller = "Home", action = "action2" }
    , new[] { "MVCApp.Controllers" }
);
routes.MapRoute(
        "rule1",
    "{controller}/{action}/{cid}/{language}/{itemID}/{uid}",
    new { controller = "Home", action = "action1" }
    , new[] { "MVCApp.Controllers" }
);

Now when I call http://localhost:51650/Home/action2/1/en/1/1 it does not route to action1 and throws exceptionThe parameters dictionary contains a null entry for parameter 'itemID' of non-nullable type 'System.Int64' for method 'System.Web.Mvc.JsonResult action1(System.String, Int32, Int64, Int64).

VSB
  • 9,825
  • 16
  • 72
  • 145
  • Invert the order. The order in which the routes are added affects how the routes works. add first rule1 and then rule2 – NicoRiff Feb 22 '17 at 17:00
  • @NicoRiff I've just updated exception details. Is there any way that information does not route to rule2 and routing skip it and take rule1 in action (for url `http://localhost:51650/Home/action2/1/en/1/1`)? – VSB Feb 22 '17 at 17:06

1 Answers1

2

You have to put first your rule1 and then your rule2 declaration. The order in which the routes are declarated is important to the api and as soon as a request match a route, then the api will stop searching for routes and go to the specified controller.

This is from the Pro ASP.NET Web API book:

Depending on your needs, you might want to have multiple Web API routes in your application. This is a totally acceptable option in ASP.NET Web API, but there are a few important things to be aware of. If you have multiple routes, the registration order of the routes matters. When a request comes to the routing level, the route collection is scanned to find a match. As soon as a match is found, the search stops, and the remaining routes get ignored. The first route registered will be looked at first, and so on.

So as your two routes have the same parameter quantity, it exits on the first route that match the request parameter quantity. To solve that, you might add constraints to your routes so you can ensure what value goes to what route, or hardcode your route to action1 in rule1 and action2 to rule2 as @Pavel as stated.

For hardcoding of action to route rule1 always to action1 and rule2 always to actoin2, use: {controller}/action1/{cid}/{language}/{itemID}/{uid} for action1 and do the same for action2 and rule2

VSB
  • 9,825
  • 16
  • 72
  • 145
NicoRiff
  • 4,803
  • 3
  • 25
  • 54
  • how can i hardcode action in rule2 or rule1? Since changing the order will lead to same error on the other action. – VSB Feb 22 '17 at 17:19
  • when someone input action1 is supposed to go to rule1 and action2 to rule2? – NicoRiff Feb 22 '17 at 17:23
  • I should note `phoneNumber` is `string` and `itemId` is `int` and when i reverse the order of rules, the `phoneNumber` will be null when information is routed to action2 . – VSB Feb 22 '17 at 17:23
  • `when someone input action1 is supposed to go to rule1 and action2 to rule2` --> Yes, that's right – VSB Feb 22 '17 at 17:24
  • 2
    use: "{controller}/action1/{cid}/{language}/{itemID}/{uid}" for action1 and do the same for action2 and rule2 – NicoRiff Feb 22 '17 at 17:32
  • @VSB - See [Why map special routes first before common routes in asp.net mvc?](http://stackoverflow.com/a/35674633/181087) for another explanation of why this happens and more possible solutions. – NightOwl888 Feb 22 '17 at 18:19