MVC 核心中的多个负载 api

Multiple payloads in MVC core rest api

我正在按照 MVC 模式在 .Net core 2.2 上开发 rest api。

我有一个带有 post 方法的控制器...

// POST: api/Todo
[HttpPost]
public async Task<ActionResult<TodoItem>> PostTodoItem(string param, [FromBody] TodoItem item)
{
    // some work... 

    return CreatedAtAction(nameof(GetTodoItem), new { id = item.Id }, item);
}

而且效果很好。

客户要求在同一路线上有一个 api,但 Json 主体可以有 2 个不同的结构,在不同的模式上承载相同的数据。

我考虑过使用

PostTodoItem(string param, [FromBody] Object item)
{
// TryCast item to one of the possible POCO classes then work with the correct one. 
} 

您是否知道更好的方法,也许使用一些高级路由和过滤选项?

这既不可能也不可取。几乎 REST 的核心租户是唯一代表特定资源的 URI。如果你有一个像 POST /todo 这样的 URI,那么 post 主体应该是一个 "todo" 并且它应该基于它创建一个新的 "todo"。在这里,那是一个 TodoItem,所以那是 all,应该 posted。

除了 REST,这是行不通的。当您的操作被激活时,模型绑定器会尝试将 post 主体绑定到操作接受的参数。它基本上只是更新参数的类型,然后尝试从 post 主体中找到一些东西以绑定到该类型的各种属性。这是对正在发生的事情的有意简单化描述;重要的部分是参数的类型告知 post 主体是如何绑定的。如果您绑定到 object(没有成员)甚至是基类型,那么将绑定的 post 主体的唯一成员是那些存在于该类型上的成员,而不是派生类型其中。任何无法绑定的东西都会被丢弃。

总而言之,您需要针对所处理的每种类型的事物制定独特的路线。在幕后,您可以通过将通用功能分解为私有方法、采用继承等方式来共享或以其他方式重用代码,但您需要不同的操作和路由来处理每种情况。