3

I have a base controller as with 2 actions:

    [ActionName("Find")]
    [HttpGet]
    public virtual IHttpActionResult Find(string name)
    {
        return null;
    }

    [ActionName("Find")]
    [HttpGet]
    public virtual IHttpActionResult Find(int number)
    {
        return null;
    }

Some of my controllers use the different Find method, for example:

    public override IHttpActionResult Find(string number)
    {
        return OK;   
    }

However, I get an error when calling this action from the client:

Multiple actions were found that match the request: \r\nFind on type API.Controllers.CustomerController

How can I solve this problem?

Ivan-Mark Debono
  • 15,500
  • 29
  • 132
  • 263

3 Answers3

4

The only way to solve this is by changing the ActionName attribute for one of the actions.

ASP.NET MVC /Web API doesn't support two actions with the same name and same HTTP verb in the same controller.

Also take a look at this question (ASP.NET MVC ambiguous action methods) if you want to go for the 'hack solution' (my opinion).

Community
  • 1
  • 1
Patrick Hofman
  • 153,850
  • 22
  • 249
  • 325
1

Why don't you just pass both parameters to the same action method? And inside your method simply check if they are null and do something about it.

Use string and int? (nullable int) to allow both parameters to contain nulls.

This way you get to use one view without any attribute jiggery pockery.

Paul Zahra
  • 9,522
  • 8
  • 54
  • 76
1

I think, you should reconsider your endpoint structure:

An action that selects one element from a resource collection should do that along the key of the resource (i.e. the unique database key). This key can be either of type int or alphanum, but not both.

What you probably want to realize with one or both of your finds, is to establish a filter function. Filter parameters should be passed to REST endpoints as query string parameters.

Examples:

  1. /api/employees → returns resource set with all employees
  2. /api/employees/5 → returns single resource (one employee)
  3. /api/employees?name=john → returns resource set with all employees named "john"

Example 3 is a filter, and I guess at least one of your finds is just that.

Jpsy
  • 20,077
  • 7
  • 118
  • 115