如何 POST 派生实体到基本实体集

How to POST a derived entity to a base entity set

假设我有一个名为 Employee 的基本实体类型和一个名为 Manager 的派生实体类型。所有员工的集合可在 /Employees URL 访问。 POST 将 Manager 的实例添加到 Employees 实体集的正确方法是什么?

OData v4 protocol spec 说 "To create an entity in a collection, the client sends a POST request to that collection's URL." 但是规范没有说明在存在派生类型的情况下指定 POSTed 实体的类型。

URI spec 说派生类型应该在目标 URL 上使用强制转换段来解决。例如,

POST /Employees/NS.Manager
{ "Name": "Bill Lumbergh" ... }

同时,JSON Format spec 建议使用 odata.type 注释,如下所示:

POST /Employees
{ "@odata.type": "#NS.Manager", "Name": "Bill Lumbergh" ... }

那么哪个是正确的?或者两者都是?

请记住,我问的是 OData 规范,而不是特定的 OData library/framework(例如 ASP.NET)。

在我看来,两者都是正确的,但是有一点不同。

对于#1,

POST /Employees/NS.Manager
{ "Name": "Bill Lumbergh" ... }

您将获得一个 Manager 实例。因此,您可以直接访问定义为 Manager.

的 属性

对于#2,

POST /Employees
{ "@odata.type": "#NS.Manager", "Name": "Bill Lumbergh" ... }

您将获得一个 Employee 实例。因此,您应该将实例转换为 Manager 然后访问 Manager 属性.

来自网络API OData 实现方面:

对于#1,它将在EmployeesController

中调用以下方法
public IHttpActionResult PostFromManager(Manager manager)
{ ... }

而对于 #2,它将在 EmployeesController

中调用以下方法
public IHttpActionResult Post(Employee employee)
 { ... }

从 OData 协议的角度来看,如果您在从目标类型派生的 JSON 请求中指定一个实例,您应该包含 @odata.type 注释。您不需要在 POST 上指定转换段(尽管有些实现可能支持,有些可能不支持)。

所以我希望你的第二个例子是最具互操作性的。

迈克·皮佐 共同编辑,OASIS OData 规范