Reputation: 3108
I'm creating a rest API in ASP.NET MVC4, and am having a problem with routing. For reference, I've already read these questions but they haven't answered my problem:
The urls I'm looking to craft can be as follows:
As you can see, in some cases the URL after the controller name maps to a parameter (id and name in #1,2 above), and sometimes the action name (#4 above). In addition, it may be not present at all (#3 above), in which case I assume a default action. Here is the routing that is working for almost all cases:
// Match for an id next.
config.Routes.MapHttpRoute(
name: "WithIdApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { action = "Index" },
constraints: new
{
id = @"^(\{{0,1}([0-9a-fA-F]){8}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){12}\}{0,1})$"
}
);
// Match for a name next.
config.Routes.MapHttpRoute(
name: "WithNameApi",
routeTemplate: "api/{controller}/{name}",
defaults: new { action = "Index" }
);
// Match for an action last.
config.Routes.MapHttpRoute(
name: "WithActionApi",
routeTemplate: "api/{controller}/{action}",
defaults: new { action = "Index" }
);
This code works for everything except example #4 above, because MVC can't tell the difference between a 'name' parameter, and an 'action' binding. If I change the order (i.e. put the match for action above), then the 'name' parameter example will never work.
Does anyone know of any way I can accomplish this?
Upvotes: 1
Views: 226
Reputation: 3108
Well for anyone else trying to do this, the answer is it isn't possible. Best thing to do is to move the 'name' search into it's own action. For example:
I would have assumed MVC would have attempted to match parameters, or actions, if one or the other failed and other bindings were available, but sadly this is not the case.
Upvotes: 1