LukeHennerley
LukeHennerley

Reputation: 6434

Custom route with action in the controller

In my RouteConfig I have:

public static void RegisterRoutes(RouteCollection routes)
{
  routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

  routes.MapRoute("ApiController", "api/{controller}");

  routes.MapRoute("ApiControllerAndIntegerId", "api/{controller}/{id}", null, new { id = @"^\d+$" });

  routes.MapRoute("ApiControllerActions", "api/{controller}/{action}");
}

I then have a LookupController.

public class LookupsController : ApiController
{
  public string Get()
  {
    return "Default Get";
  }
  // /api/lookups/custom
  [ActionName("custom")]
  public string CustomLookup()
  {
    return "Hello, World";
  }
}

If I navigate to /api/lookups/custom I still get Default Get instead of Hello, World. What am I doing wrong?

Edit

I have tried the different variants of MapHttpRoute and MapRoute. Neither seem to work.

Upvotes: 1

Views: 1616

Answers (2)

cuongle
cuongle

Reputation: 75306

You are using the wrong config route for Web Api, it should be MapHttpRoute instead of MapRoute:

var configuration = GlobalConfiguration.Configuration;

     configuration.Routes.MapHttpRoute(
          name: "CustomizedApi",
          routeTemplate: "api/{controller}/{action}/{id}",
          defaults: new { id = RouteParameter.Optional }
      );

        configuration.Routes.MapHttpRoute(
            name: "DefaultApi",
            routeTemplate: "api/{controller}/{id}",
            defaults: new { id = RouteParameter.Optional }
        );

Please note that: put the route "api/{controller}/{action}/{id}" on top of "api/{controller}/{id}"

Also, mark [HttpGet] in your CustomLookup to support GET method for this action:

// /api/lookups/get
public string Get()
{
    return "Default Get";
}

// /api/lookups/custom
[ActionName("custom")]
[HttpGet]
public string CustomLookup()
{
    return "Hello, World";
}

it will work

Upvotes: 1

anaximander
anaximander

Reputation: 7140

MVC Routes are checked in the order you define them. You're having trouble with /api/lookups/custom, which is supposed to hit "api/{controller}/{action}". However, before that you have "api/{controller}/{id}" and "api/{controller}", so it looks like one of those is catching it. My guess would be that it's trying to parse "custom" as {id} in the first of those two. I notice you're not specifying default controllers or actions in your routes; it's possible you took them out before posting to take less space, but if you haven't specified defaults I recommend you do so - whether or not it's capable of picking its own defaults, it can be useful to know what your program's "I don't know what to do" behaviour is.

Reverse the order you're specifying those three routes in. When in doubt, put your longest and most specific routes up top, and then get gradually more vague. Putting more generic routes up top tends to result in those routes catching things that should have gone to more specific route definitions further down.

Upvotes: 2

Related Questions