Search code examples
c#restasp.net-web-api2asp.net-web-api-routing

Web Api how to define 2 methods with same parameters


I'm new to Web API. Reading up on restful made me think it was based upon verbs and as such I was hoping that the logic would be as well.

If I want to create an API for Delete and Get, which have the same signature I'm told off .

[HttpGet]
public HttpResponseMessage Index(int id)
{
    return Request.CreateResponse(HttpStatusCode.OK, GetValue());
}

[HttpDelete]
public HttpResponseMessage Index(int id)
{
    //logic
    return Request.CreateResponse(HttpStatusCode.OK, true);
}

I was hoping by specifying the different verb Web Api 2 would tell. But even if I update the delete to (note the void return type)

[HttpDelete]
public void Index(int id)
{
    //logic
}

I am still told off as the member called index with the same parameter types already exist.

According to https://learn.microsoft.com/en-us/aspnet/web-api/overview/advanced/calling-a-web-api-from-a-net-client it shows

Action               HTTP method    Relative URI
Get a product by ID      GET            /api/products/id
Create a new product     POST           /api/products
Update a product         PUT            /api/products/id
Delete a product         DELETE         /api/products/id

The Get, Put and Delete have the same URL. Sadly, they don't display the server side code, only the client.

Are my only options to:

1. Overload the method (in this example, seems like it would be hacking as it's not needed to perform the required task)
2. Give the method a different name (eg `Delete` instead of `Index`)

Or is there another way?


Solution

  • You have a syntax issue. You can use attribute routes to maintain same paths but the methods must have different names and structures or you will get compilation error like you already experienced.

    Using the example from your question

    Action                 HTTP method    Relative URI
    Get a product by ID      GET            /api/products/id
    Create a new product     POST           /api/products
    Update a product         PUT            /api/products/id
    Delete a product         DELETE         /api/products/id
    

    The following would be a controller that matches the above

    [RoutePrefix("api/products")]
    public class ProductsController : ApiController {
    
        [HttpGet]
        [Route("{id:int}")] //Matches GET api/products/1
        public IHttpActionResult Get(int id) {
            return Ok(GetValueById(id));
        }
    
        [HttpPost]
        [Route("")] //Matches POST api/products
        public IHttpActionResult Post([FromBody]Product model) {
            //...code removed for brevity
        }
    
        [HttpPut]
        [Route("{id:int}")] //Matches PUT api/products/1
        public IHttpActionResult Put(int id, [FromBody]Product model) {
            //...code removed for brevity
        }
    
        [HttpDelete]
        [Route("{id:int}")] //Matches DELETE api/products/1
        public IHttpActionResult Post(int id) {
            //...code removed for brevity
        }
    }