cpeele00
cpeele00

Reputation: 893

Custom ASP.NET WebAPI route not working. Action never gets hit

I am trying to get a route to work in ASP.NET WebAPI and need some assistance.

This is my default GET that maps to perfectly to GetFeedbackPosts(id As string) in my api controller

  /api/feedbackPost/id

However, I also need another GET "action" or method if you will in that same api controller that is called GetFeedbackPostCategories(). I am trying to access it with the following uri:

/api/feedbackPost/getFeedbackPostCategories

The GetFeedbackPostCategories() method never gets hit,...it always hits GetFeedbackPosts()

These are my routes:

    RouteTable.Routes.MapHttpRoute(
        name:="DefaultApi",
        routeTemplate:="api/{controller}/{id}",
        defaults:=New With {Key .id = RouteParameter.Optional})


    RouteTable.Routes.MapHttpRoute(
        name:="MVCActionStyleApi",
        routeTemplate:="api/{controller}/{action}/{id}",
        defaults:=New With {Key .id = RouteParameter.Optional})

I am trying to target the one named "GeneralApi". However, like I said, it keeps hitting the wrong action, (the other Get action on the controller). Any Ideas?

Thanks!

Upvotes: 0

Views: 3574

Answers (2)

rock_walker
rock_walker

Reputation: 473

Just leave your second route and update it with default value of action = "GetFeedbackPosts":

RouteTable.Routes.MapHttpRoute(
  name:="MVCActionStyleApi",
  routeTemplate:="api/{controller}/{action}/{id}",
  defaults:=New With {Key .id = RouteParameter.Optional,
                      Key .action = "GetFeedbackPosts"})

P.S. sorry for syntax, seems it's VB.

Then, you'll be able to request the first URL

/api/feedbackPost/id

by modified one /api/feedbackPost/GetFeedbackPosts/id, but without id it is possible: /api/feedbackPost.

Thus your second URL /api/feedbackPost/getFeedbackPostCategories will work originally and You can add many other Get actions.

But I recommend You to use attributes [ActionName] before declaring actions in controller to exclude requesting this evident long verbs with get word in name and transform to nouns like this: /api/feedbackPost/feedbackPostCategories.

Proof link -> Web API Design: Crafting Interfaces that Developers Love

Upvotes: 0

Mike Wasson
Mike Wasson

Reputation: 6622

The first route will match any URI with the form /api/something/something, so the second route won't be matched in this case.

In general, mixing "{action}" routes with non-action routes in Web API doesn't work very well. Even if you can get the routing to work, you usually hit problems with action selection.

For example, if you send a GET request for /api/feedbackPost, the action selection can't distinguish these two methods, so you'll get a "multiple matching actions" error

public class FeedbackPost : ApiController
{
    public HttpResponseMessage GetFeedbackPosts()

    [HttpGet]
    public HttpResponseMessage GetFeedbackPostCategories()
}

Depending on your exact scenario, one option is to treat "FeetbackPostCategories" as a separate resource and create a "Categories" controller, and use GET /api/categories.

Or, Web API 2 (currently in RC) supports attribute-based routing, which would let you handle this case.

Upvotes: 1

Related Questions