如何使用ASP.Net WebApi重载方法?

时间:2013-04-04 14:03:57

标签: c# asp.net asp.net-web-api put

我有一种情况,我有两个方法,一个接受poco,另一个poco列表在我的控制器类中:

[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);
}

我的路由表看起来像:

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
                    });

这可以按预期工作。但我想重构代码以尝试重载。我试图重载我的控制器中的方法,只有一个路由但它失败了500错误 - 无效请求。我认为webapi将通过验证参数来解析调用 - 如果它是一个列表,那么它将使用list作为参数调用重载方法,否则调用另一个方法。我打算做一些像:

[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);
}

我的路由表看起来像:

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

2 个答案:

答案 0 :(得分:2)

Web API使用名为IHttpActionSelector的东西来确定在控制器中调用哪个动作。我认为默认实现不支持这样的场景的重载。您可以实现自定义IHttpActionSelector,但它可能需要做很多工作。请查看此博客文章中的示例

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

支持一个总是收到项目列表的场景会简单得多。对于一个项目的情况,它只是一个包含单个项目的列表。

答案 1 :(得分:1)

我怀疑路由不考虑身体。在您的情况下,确定使用哪个重载的唯一方法是正确解析正文和路由。您可以做的一个简化是始终使用单个方法获取Item列表。然后,在单个项目的情况下,只需在列表中包含该项目。