【问题标题】:How to patch enumerables and guids with OData V4 Delta in Asp.Net.Core 3.1如何在 Asp.Net.Core 3.1 中使用 OData V4 Delta 修补枚举和指导
【发布时间】:2020-07-07 05:18:18
【问题描述】:

我正在使用 Microsoft.AspNetCore.OData nuget v7.3.0 和 Microsoft.EntityFrameworkCore v3.1.1 开发新的 ASP.NET Core 3.1 API

我正在使用 Postman v7.21.0 来测试 API。

GET 和 POST 似乎一切正常,但使用 PATCH,我似乎只能更新字符串。如果我尝试更新作为 GUID 或 ENUM 的实体字段,它不会执行更新并且我不会收到任何类型的错误。

如果我在请求正文中使用以下 JSON 调用 HTTP PATCH;

{
    "@odata.context": "https://localhost:44367/odata/$metadata#Account",
    "AccountName": "Test Account 1"
}

增量正确更新 AccountName 字段,这是一个字符串。

但是,如果我在请求正文中使用以下 JSON 调用 HTTP PATCH;

{
    "@odata.context": "https://localhost:44367/odata/$metadata#Account",
    "OwnerId": "f9d1f8c7-2cbb-4156-0031-08d7d0f9edd5"
}

如果 OwnerID 是 GUID,我没有收到任何错误,但 OwnerId 值未在数据库中更新。

同样,如果我在请求正文中使用以下 JSON 调用 HTTP PATCH;

{
    "@odata.context": "https://localhost:44367/odata/$metadata#Account",
    "Status": "Inactive"
}

Status 是一个 ENUM,它也不会随更改更新数据库。

在我的元数据中,Status 列为 Type="MyApi.Enums.StatusTypes" 而 OwnerId 列为 Type="Edm.Guid"。

我需要在请求正文中包含类型吗?

我尝试了以下方法;

{
    "@odata.context": "https://localhost:44367/odata/$metadata#Account",
    "@odata.Type": "MyApi.Enums.StatusTypes" 
    "Status": "Inactive"
}

但它仍然没有更新数据库。

这是我的 API 中 Patch 方法的帐户控制器代码;

    [ODataRoute("{id}")]
    [Produces("application/json;odata.metadata=minimal")]
    [ProducesResponseType(typeof(AccountModel), Status200OK)]
    [ProducesResponseType(Status204NoContent)]
    [ProducesResponseType(Status400BadRequest)]
    [ProducesResponseType(Status404NotFound)]
    public async Task<IActionResult> Patch(Guid id, [FromBody] Delta<Account> delta)
    {

        if (!ModelState.IsValid)
        {
            return BadRequest(ModelState);
        }

        var entity = await _context.Accounts.FindAsync(id);
        if (entity == null)
        {
            return NotFound();
        }

        delta.Patch(entity);
        try
        {
            await _context.SaveChangesAsync();
        }
        catch (DbUpdateConcurrencyException)
        {
            if (RecordExists(id))
            {
                return NotFound();
            }
            throw;
        }

        return Updated(delta);
    }

我在 OData.org 上找不到任何修补 GUID 或 ENUM 的示例。所有的数据修改示例都使用了字符串。

有什么想法吗?

我在这里错过了什么?

【问题讨论】:

    标签: asp.net-core entity-framework-core odata postman


    【解决方案1】:

    @whiskytangofoxtrot 假设您是从 Postman(或同等产品)访问您的服务,请确保在有效负载中包含 Enum 类型注释。如下:

    {
        "@odata.context": "{{ServiceRoot}}/$metadata#Accounts/$entity",
        "Id": "3527ba9a-f5aa-4337-b7bb-dfe634b15e57",
        "OwnerId": "3527ba9a-f5aa-4337-b7bb-dfe634b15e57",
        "Status@odata.type": "#NS.AccountStatus",
        "Status": "InActive"
    }
    

    NS{{ServiceRoot}} 替换为特定于您的方案的命名空间和服务根(分别)。至于 Guid,你不需要做任何具体的事情。

    查找我成功尝试的屏幕截图: 请求:

    结果:

    【讨论】:

      【解决方案2】:

      当你有 guid 的数组列表时,你是如何管理的。

      尝试更新 knownClientApplications 时出现以下错误, 错误:“无法将原始值转换为预期类型 'Edm.Guid'”

      API 参考:https://docs.microsoft.com/en-us/graph/api/resources/apiapplication?view=graph-rest-1.0

      在 powershell 7.0 中执行的命令

      az rest `
       --method PATCH `
       --uri "https://graph.microsoft.com/v1.0/applications/000000000-0000-00000-0000" `
       --headers "Content-Type=application/json" `
       --body '{\"api\" : {\"knownClientApplications\": [\"000000-0000-0000-000000\"]}}
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2015-10-15
        • 1970-01-01
        • 1970-01-01
        • 2014-10-18
        • 2015-05-30
        • 2016-07-05
        • 1970-01-01
        相关资源
        最近更新 更多