Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to work with ASP.Net WebApi overloaded methods?

I have a situation where I have two methods one accepts a poco and another list of poco in my controller class:

[AcceptVerbs("PUT")]
[ActionName("Item")]
public void SaveItem([FromBody] Item item)
{
    m_controller.SaveItem(item);           
}

[AcceptVerbs("PUT")]
[ActionName("Items")]
public void SaveItems([FromBody] List<Item> items)
{
    m_controller.SaveItem(items);
}

my routing table looks something like:

routes.MapHttpRoute("Item Route",
                    "api/item/{orderId}",
                    new
                    {
                        controller = "MyOrder",
                        action = "Item",
                        orderId = RouteParameter.Optional
                    });

routes.MapHttpRoute("Items Route",
                    "api/items/{orderId}",
                    new
                    {
                        controller = "MyOrder",
                        action = "Items",
                        orderId = RouteParameter.Optional
                    });

This works as expected. But I thought of refactoring the code to try overloading. I tried to overload the methods in my controller and have just one route but it failed with 500 error - Invalid Request. I thought webapi will resolve the call by verifying the parameter - if it is a list then it will call the overloaded method with list as parameter otherwise the other method. I was planning to do something like:

[AcceptVerbs("PUT")]
[ActionName("Item")]
public void SaveItem([FromBody] Item item)
{
    m_controller.SaveItem(item);           
}

[AcceptVerbs("PUT")]
[ActionName("Item")]
public void SaveItem([FromBody] List<Item> items)
{
    m_controller.SaveItem(items);
}

my routing table looks something like:

routes.MapHttpRoute("Item Route",
                    "api/item/{orderId}",
                    new
                    {
                        controller = "MyOrder",
                        action = "Item",
                        orderId = RouteParameter.Optional
                    });
like image 212
Sri Reddy Avatar asked Apr 04 '13 14:04

Sri Reddy


2 Answers

Web API uses something called IHttpActionSelector to determine which action to invoke in the controller. I think the default implementation does not support overloads for scenarios like this. You can implement a custom IHttpActionSelector, but it might a lot of work. Take a look at the samples in this blog post,

http://www.novanet.no/blog/aanund-austrheim/dates/2012/7/several-post-methods-on-an-apicontroller-using-an-actionselector/

It would be much simpler to support a single scenario where you always receive a list of items. For the case of one item, it's just a list with a single item.

like image 105
Pablo Cibraro Avatar answered Oct 22 '22 17:10

Pablo Cibraro


I suspect that the routing doesn't take the body into account. In your case, the only way to determine which overload to use is to parse the body and route appropriately. One simplification you could do is to always take a list of Item with a single method. Then in the case of a single item, just include that one item in the list.

like image 34
Jim Wooley Avatar answered Oct 22 '22 16:10

Jim Wooley