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
});
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With