ODATA客户端无法为关键属性发送空值



我已经建立了一个ODATA WebAPI服务,以公开几个实体(使用ODATA 4,System.Web.odata v5.1.9)。

服务接受BOST帖子(用于创建)和补丁(用于更新)。在内部,POST和PAITS均被转发到Oracle数据库,并且通过单个存储过程来处理这两种方法,该过程将ID作为输入参数。如果ID为null,则创建新记录,否则已更新了具有该ID的记录。

最近我们的一位消费者抱怨说,他们无法正确插入新数据。问题在于他们使用ODATA客户端使用元数据来生成其模型。由于ID不可自然,总是将0发送到我的服务,并提示数据库例程使用ID 0进行记录更新(不存在,提高例外)。

现在,我看到有几个选项可以绕过以下内容:

  • 在我的控制器中检查ID是否默认(int),如果是这样,则将null传递给SP
  • 停止使用ODATA客户端,并让他们手动构造他们的消息
  • 将单个存储过程分为两个过程(插入和更新)
  • 将ID属性更改为字符串

我的实体类看起来像这样:

public class ContactDTO
    {
        [Key]
        public int Id { get; set; }
        [ForeignKey("Person")]
        public int? PersonId { get; set; }
        // snip some other properties
    }

由于ID属性定义为[键],因此根据需要在元数据中显示:

<EntityType Name="ContactDTO">
    <Key>
        <PropertyRef Name="Id"/>
    </Key>
    <Property Name="Id" Type="Edm.Int32" Nullable="false"/>
    <Property Name="PersonId" Type="Edm.Int32"/>
</EntityType>

我有一种感觉,我在这里错过了一些东西,也许我应该像以前一样离开它,但是如果没有,我可以采取什么步骤来确保他们可以正确地致电我的服务

  1. Id属性定义为无效,然后在其上删除 KeyAttribute

    public class ContactDTO
    {
        public int? Id { get; set; }    
        [ForeignKey("Person")]
        public int? PersonId { get; set; }
    } 
    
  2. Id属性配置为键,并将其配置为可选:

    ODataConventionModelBuilder modelBuilder = new ODataConventionModelBuilder();
    modelBuilder.EntityType<ContactDTO>().HasKey(_ => _.Id);
    modelBuilder.EntityType<ContactDTO>().Property(_ => _.Id).IsOptional();
    

它产生以下元数据:

<EntityType Name="ContactDTO">
    <Key>
        <PropertyRef Name="Id" />
    </Key>
    <Property Name="Id" Type="Edm.Int32" />
    <Property Name="PersonId" Type="Edm.Int32" />
</EntityType>

最新更新