使用 Http Patch 上的对象列表的最佳方法
Posted
技术标签:
【中文标题】使用 Http Patch 上的对象列表的最佳方法【英文标题】:Best way to work with list of objects on Http Patch 【发布时间】:2020-10-21 07:46:08 【问题描述】:在我的场景中,我有一个 Web 客户端,并且 Web 客户端中的 rest api (.NET Core) 有一个列出所有客户端的页面,在此列表中,用户可以选择许多客户端并将它们标记为已启用。 如何在我的 api 中处理“标记为启用”? 我可以在方法 PATCH 上一一更新,但对于列表我不知道如何。
public IActionResult Patch( long id, [FromBody] JsonPatchDocument<Client> patch )
var client = base.DataContext.Clients.Find( id );
if( client != null )
patch.ApplyTo( client, ModelState );
return Ok();
public class Client
public string Name get; set;
public string Description get; set;
public bool Enabled get; set;
【问题讨论】:
嗨 Luis,你会在这里找到很多帮助,但现在你的问题太笼统了,首先你需要展示你已经尝试过的内容,你遇到的具体问题是什么,你一直无法找到答案 【参考方案1】:修补List的HttpPatch
动作与Object相同。
[HttpPatch]
public IActionResult JsonPatchForClients([FromBody] JsonPatchDocument<List<Client>> patchDoc)
var clients = CreateClients();
patchDoc.ApplyTo(clients);
return new ObjectResult(clients);
private List<Client> CreateClients()
return new List<Client>()
new Client
Name = "Client0",
Description = "Description0",
Enabled = true
,
new Client
Name = "Client1",
Description = "Description1",
Enabled = true
,
new Client
Name = "Client2",
Description = "Description2",
Enabled = true
;
public class Client
public string Name get; set;
public string Description get; set;
public bool Enabled get; set;
接下来,我将详细介绍如何发送Patch
Body。
这是原始列表:
[
"name": "Client0",
"description": "Description0",
"enabled": true
,
"name": "Client1",
"description": "Description1",
"enabled": true
,
"name": "Client2",
"description": "Description2",
"enabled": true
]
1.添加到“/-
”数组的末尾,并添加到“/0
”数组的第一个
[
"op": "add",
"path": "/-",
"value":
"name": "Order3",
"description": "Description3",
"enabled": true
]
结果:
[
"name": "Client0",
"description": "Description0",
"enabled": true
,
"name": "Client1",
"description": "Description1",
"enabled": true
,
"name": "Client2",
"description": "Description2",
"enabled": true
,
"name": "Order3",
"description": "Description3",
"enabled": true
]
2。替换 Order3
为 Order0
[
"op": "replace",
"path": "/0",
"value":
"name": "Order3",
"description": "Description3",
"enabled": true
]
结果:
[
"name": "Order3",
"description": "Description3",
"enabled": true
,
"name": "Client1",
"description": "Description1",
"enabled": true
,
"name": "Client2",
"description": "Description2",
"enabled": true
]
3.Remve Client0
[
"op": "remove",
"path": "/0"
]
结果:
[
"name": "Client1",
"description": "Description1",
"enabled": true
,
"name": "Client2",
"description": "Description2",
"enabled": true
]
-
其他(
move
,copy
,test
)你可以在microsoft doc找到。
【讨论】:
但这是数组“path”的顺序:“/0”,如果顺序改变我会更新一个错误的项目。我的页面必须知道我的列表的 a 项目位置,但是这个列表来自 DB,并且会被排序、过滤等等。 无法通过某些属性从数组中选择元素。对于更新对象列表,您应该考虑放弃 JsonPatch。 JSONPatch 旨在以非常明确的方式更新 API 上的文档。【参考方案2】:另一种方式是replace
all。
[HttpPatch]
public IActionResult JsonPatchForClients([FromBody] JsonPatchDocument patchDoc)
var clients = new Clients();
patchDoc.ApplyTo(clients);
return new ObjectResult(clients);
public class Clients
public List<Client> clients get; set;
public Clients()
clients = new List<Client>()
new Client
Name = "Client0",
Description = "Description0",
Enabled = true
,
new Client
Name = "Client1",
Description = "Description1",
Enabled = true
,
new Client
Name = "Client2",
Description = "Description2",
Enabled = true
;
JSONPatch 的主体:
[
"op": "replace",
"path": "/clients",
"value": [
"name": "clients1",
"description": "Desc1",
"enabled": false
,
"name": "clients2",
"description": "Desc2",
"enabled": false
]
]
这样,我们可以更新列表的每个对象。但这与正常方式非常相似(将模型传递给行动)。
【讨论】:
嗨 Luis,你试过全部替换吗?同时,我认为 HTTP PATCH 不是在您的情况下更新列表对象的好方法。 HTTP PUT vs HTTP PATCH 从这里看到baeldung.com/http-put-patch-difference-spring 如果坚持使用HTTP PATCH,请逐个尝试补丁,但不要列出。以上是关于使用 Http Patch 上的对象列表的最佳方法的主要内容,如果未能解决你的问题,请参考以下文章
批处理位于 Google Cloud Storage Bucket 上的对象的最佳方法
无效的 HTTP 方法:PATCH > 正在执行 PATCH :引起:feign.RetryableException: