【问题标题】:Update certain fields from API request architecture or design pattern with ASP.NET Web API使用 ASP.NET Web API 从 API 请求架构或设计模式更新某些字段
【发布时间】:2017-10-18 17:32:36
【问题描述】:

我有一个 API 可以更新已经存在的实体。该实体可以通过 API 所在的接口手动更新。

我的问题是,关于如何仅更新供应商可能通过实体上的 API 发送的某些字段,什么是好的设计模式或架构?我不想仅仅因为它们在发送到 API 时不知道这些值而用 NULL 或空字符串覆盖字段,但是数据库中的实体可能已经具有该字段的值。

这也应该考虑到供应商是否希望将字段重置为某种空字符串。

实体 API 模型

ID
Name
TwitterHandle

具有值的实体数据库模型

ID = 200
Name = Hello
TwitterHandle = @hello

实体请求模型发送到带有值的 API

ID = 200
Name = Hello2

此请求应仅将名称更新为 Hello2,但不理会 TwitterHandle。但是,在另一个请求中,他们可以重置 TwitterHandle,如果发送了一些东西(NULL,空字符串)

【问题讨论】:

  • 我建议接受仅包含能够为特定调用编辑的属性的 ViewModel 或 DTO。这意味着您可能会有多个。不要通过您的 API 来回发送实体。
  • 我有 100 个客户端使用这个 API,所以我不会为每个客户端创建一个模型

标签: .net api post asp.net-web-api asp.net-web-api2


【解决方案1】:

我们过去做过的一件事是创建一个端点“http://webapi.com/twitter/200/name”,然后执行一个包含更新值的 put。它并不完美,但它可以完成工作并且很容易实现。

【讨论】:

  • 越来越近了,但他们可能想要更新多个属性。我也不希望他们发送逗号分隔的列表。我宁愿发送一个对象,以通用方式验证缺少哪些字段,并且只更新 put 请求中的字段。
  • 此时唯一要做的事情就是类似于补丁,你可以使用 JsonObject 但你的映射配置不会很有趣。请记住,空值已从 json 中删除,因此无法判断它们是否发送了空值。
【解决方案2】:

如果您想在 API 级别执行此操作,则可以使用以下 HttpPatch

public void Patch(Guid id, JsonPatchDocument<SomeDto> patch) {
    // Perform validation
    var objectToUpdate = repo.GetById(id); // replace this with your database call
    patch.ApplyUpdatesTo(objectToUpdate); 
    repo.Save(objectToUpdate); // save it to database
}

我会采取的另一种方法是使用 Automapper。在那里,我将创建 dto 对象和自动映射器映射类,它将 dto 转换为数据库模型。这样您也将遵循单一责任原则,因为您的映射将成为自动映射器配置的责任

【讨论】:

  • 好建议。补丁似乎有一堆额外的东西,你必须发送来做我不想要的更新。我们已经使用了 automapper,所以我们可以为这个场景做一个映射,但又是什么决定了哪些属性应该被更新。我认为最好的选择是手动序列化请求并测试请求中的属性是否可用,然后更新数据库模型属性,这两个属性必须准确。
【解决方案3】:

我认为我找到了 Newtonsoft 的解决方案

JsonConvert.PopulateObject

Populate Object

【讨论】:

  • 你测试了吗?因为它不适合我。我用动态对象尝试了他们的示例,但在 PopulateObject 方法之后没有注意到我的对象有任何变化
  • 是的,我测试过?
猜你喜欢
  • 2015-04-14
  • 2017-09-05
  • 1970-01-01
  • 1970-01-01
  • 2021-06-18
  • 1970-01-01
  • 2015-10-27
  • 1970-01-01
  • 2015-07-27
相关资源
最近更新 更多