user1352057
user1352057

Reputation: 3182

WebApi - Multiple GET actions with identical signatures - routing issue

Question Background:

I have a single controller within my WebApi that has two action methods. These two actions methods are both GET's and have no parameters.

One action method is named 'GetMessages', the other 'GetEmployeeList'.

The Issue:

These are the following action Methods in my Controller:

[HttpGet]
public string GetMessages()
{
  return "Get Messages Endpoint";
}

[HttpGet]
public string GetEmployeeList()
{
    return "Get Employees Endpoint";
}

These are the customs routes I have set with the WepApiConfig

  config.Routes.MapHttpRoute(
  name: "Messages",
  routeTemplate: "v2/api/People/{action}/{id}",
  defaults: new { action = "GetMessages", id = RouteParameter.Optional });


   config.Routes.MapHttpRoute(
   name: "Employees",
   routeTemplate: "v2/api/People/{action}/{id}",
   defaults: new { action = "GetEmployeeList", id = RouteParameter.Optional});

When I call either pf the following URL's:

/v2/api/People/GetMessages
/v2/api/People/GetEmployeeList

I receieve the following exception messaging stating that multiple actions match the URL request:

Multiple actions were found that match the request: System.Net.Http.HttpResponseMessage GetMessages() on type Persons.PeopleController System.Net.Http.HttpResponseMessage GetEmployeeList() on Persons.PeopleController

How Can I rectify this so I an use two GET action methods together which have the same signature?

Upvotes: 2

Views: 1313

Answers (3)

fjompen
fjompen

Reputation: 73

You dont need to have two routes. One is enough. Try changing your route to the following.

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

You can try to specify your routes separately, but you shouldnt have to. Make sure your call to the web api is 100% correct.

Upvotes: 1

Václav Holuša
Václav Holuša

Reputation: 311

What about specifying route for every method separately?

[RoutePrefix("api/people")]
public class MyController : ApiController
{
    [HttpGet]
    [Route("messages")]
    public string GetMessages()
    {
      return "Get Messages Endpoint";
    }

    [HttpGet]
    [Route("employees")]
    public string GetEmployeeList()
    {
        return "Get Employees Endpoint";
    }
}    

so you will the have your URLs like

/v2/api/people/messages
/v2/api/people/employees

which IMHO looks a bit more RESTful than your example

Upvotes: 1

Anton
Anton

Reputation: 2636

I might not be getting the point, but why don't you simply adjust the routes like this (please notice the action names in the route templates):

config.Routes.MapHttpRoute(
  name: "Messages",
  routeTemplate: "v2/api/People/GetMessages/{id}",
  defaults: new { action = "GetMessages", id = RouteParameter.Optional });

config.Routes.MapHttpRoute(
   name: "Employees",
   routeTemplate: "v2/api/People/GetEmployeeList/{id}",
   defaults: new { action = "GetEmployeeList", id = RouteParameter.Optional});

However I would rather go with a more generic option:

config.Routes.MapHttpRoute(
  name: "People",
  routeTemplate: "v2/api/People/{action}/{id}",
  defaults: new { id = RouteParameter.Optional });

This way you can cover both of the actions with a single route. Is there any reason not to choose this option?

Upvotes: 3

Related Questions