【问题标题】:How to POST a derived entity to a base entity set如何将派生实体发布到基础实体集
【发布时间】:2019-11-18 22:02:57
【问题描述】:

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

OData v4 protocol spec 表示“要在集合中创建实体,客户端会向该集合的 URL 发送 POST 请求。”但是规范没有说明在派生类型存在的情况下指定 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 库/框架(例如 ASP.NET)。

【问题讨论】:

    标签: odata


    【解决方案1】:

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

    因此,我希望您的第二个示例是最具互操作性的。

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

    【讨论】:

    • 感谢您的回答。我期待 POST-with-cast 方法更受欢迎,但经过反思,我认为 JSON 有效负载是自描述的更有意义。但是,@odata.type 属性的值(指向元数据文档的 URI)不如强制转换段的值(命名空间限定的类型名称)那么明显。
    【解决方案2】:

    在我的选择中,两者都是正确的,但是有一点不同。

    对于#1,

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

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

    对于#2,

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

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

    从 Web API OData 实现方面:

    对于#1,它将调用EmployeesController中的以下方法

    public IHttpActionResult PostFromManager(Manager manager)
    { ... }
    

    而对于#2,它将调用EmployeesController中的以下方法

    public IHttpActionResult Post(Employee employee)
     { ... }
    

    【讨论】:

    • 我认为您的 Web API 方法颠倒了。带有强制转换 (/Employees/NS.Manager) 的 URI 将被路由到 PostFromManager(),而裸 URI 将被路由到 Post()。
    • 糟糕。谢谢你的澄清。我更新了我的答案。
    猜你喜欢
    • 1970-01-01
    • 2014-04-28
    • 1970-01-01
    • 1970-01-01
    • 2011-12-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多