6

我有一种情况,我有两种方法,一种在我的控制器类中接受一个 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 将通过验证参数来解决调用 - 如果它是一个列表,那么它将调用带有列表作为参数的重载方法,否则调用其他方法。我打算做类似的事情:

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

2 回答 2

2

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

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

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

于 2013-04-04T15:03:16.940 回答
1

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

于 2013-04-04T15:00:13.800 回答