locked
Controller Methods with same name but different signature RRS feed

  • Question

  • User438705957 posted

    Hi,

    On adding the Web API controller based on my employees model, it sets up a get method in the controller that expects an integer as input.
    I understand this because id is the primary key and it provides this get method by default by convention.
    However, I want my users to be able to search by name as well.
    So I have added a method to the controller with the same name but a different signature, to the one created by default to search by id.

    //// GET: api/Employees/5
            [ResponseType(typeof(Employee))]
            public async Task<IHttpActionResult> GetEmployee(int id)
            {
                Employee employee = await db.Employees.FindAsync(id);
                if (employee == null)
                {
                    return NotFound();
                }
    
                return Ok(employee);
            }       
    
    // GET: api/Employees/Anderson       
            public IQueryable<Employee> GetEmployee(string lastName)
            { 
                return db.Employees;
            }
    
    
    

    On calling the 'search by name' webAPI using getJSON() from my webpage, an error message is posted that indicates the routing engine is still looking for an action that expects an integer as input.

    Is it allowable in Web API to have actions with identical names but different signatures, or do I have to do some magic in the route table.

    Wednesday, May 20, 2015 9:46 PM

Answers

  • User1564875471 posted

    Basically this was never been supported in MVC and it's the same in Web API. you can't have action overload by having different parameters and the reason is that when you send a request to the GetEmployee API, you send a parameter which will be received on the server as string. So the server has no way to figure out that the value received is the id or the lastName. However, if you send the parameter name + the value, the server can locate the correct function. So what you can do is to send the lastName using the traditional query string way:

    /api/employees?lastName=something

    This will ensure that the second version of GetEmployee will be called as you are explicitly telling the Web API the parameter name.

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Thursday, May 21, 2015 6:40 AM
  • User438705957 posted

    Thankyou Anas, and apologies for taking a while to respond.

    I found out after exhaustive research that in Web API 2, you can override the default routing engine and decorate your controller action with the Route attribute specifying the exact routing info you want.
    Works a charm.

    [Route("api/employees/{lastName:alpha}")]
    [ResponseType(typeof(Employee))]

    public async Task<IHttpActionResult> GetEmployeesByName(string lastName)
    {........
    }

    Thanks

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Tuesday, May 26, 2015 3:19 AM

All replies

  • User1564875471 posted

    Basically this was never been supported in MVC and it's the same in Web API. you can't have action overload by having different parameters and the reason is that when you send a request to the GetEmployee API, you send a parameter which will be received on the server as string. So the server has no way to figure out that the value received is the id or the lastName. However, if you send the parameter name + the value, the server can locate the correct function. So what you can do is to send the lastName using the traditional query string way:

    /api/employees?lastName=something

    This will ensure that the second version of GetEmployee will be called as you are explicitly telling the Web API the parameter name.

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Thursday, May 21, 2015 6:40 AM
  • User438705957 posted

    Thankyou Anas, and apologies for taking a while to respond.

    I found out after exhaustive research that in Web API 2, you can override the default routing engine and decorate your controller action with the Route attribute specifying the exact routing info you want.
    Works a charm.

    [Route("api/employees/{lastName:alpha}")]
    [ResponseType(typeof(Employee))]

    public async Task<IHttpActionResult> GetEmployeesByName(string lastName)
    {........
    }

    Thanks

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Tuesday, May 26, 2015 3:19 AM