在 ASP.NET Core 中使用 JsonPatch 将项目添加到字典
Adding an item to a Dictionary using JsonPatch in ASP.NET Core
我有以下环境和 .NET Core 版本
.NET SDK (reflecting any global.json):
Version: 5.0.100
Commit: 5044b93829
Runtime Environment:
OS Name: Mac OS X
OS Version: 11.0
OS Platform: Darwin
RID: osx.11.0-x64
Base Path: /usr/local/share/dotnet/sdk/5.0.100/
使用以下代码和端点。
public class Trie
{
public string Id { get; set; }
public Dictionary<string, TrieNode> Nodes { get; set; }
}
public class TrieNode
{
public string Name { get; set; }
}
public async Task<IActionResult> Patch(string id, [FromBody] JsonPatchDocument<Trie> patchDoc)
{
var trie = [get from database]
patchDoc.ApplyTo(trie, ModelState);
}
当我使用以下操作时:
[
{
"op": "add",
"path": "/nodes/-", "value": { "/": { "name": "hello, world" } }
}
]
一个项目被添加到字典中是这样的:
"Nodes": {
"-": {
"Name": null
}
}
如果我对操作使用以下语法
[
{
"op": "add",
"path": "/nodes", "value": { "/": { "name": "hello, world" } }
}
]
项目是这样添加的:
"Nodes": {
"/": {
"Name": "hello, world"
}
}
但是当我尝试使用另一个键添加新项目时:
[
{
"op": "add",
"path": "/nodes", "value": { "/my-key": { "name": "hello, world" } }
}
]
该项 未 添加,它替换了第一个条目,因此结果如下所示:
"Nodes": {
"/my-key": {
"Name": "hello, world"
}
}
如何添加、删除、替换、复制、移动 Dictionary 中的条目?
您使用的格式将设置整个 属性 值(到仅包含一个条目的字典)。这就是为什么您看到它已添加但未更新的原因。
对于通过密钥更新条目,看起来这在任何地方都没有记录。更新密钥(添加或更新现有密钥)的实际语法如下所示:
/path-to-dictionary/string-key
以上路径也针对 remove
的现有条目。
然后 value
应该只是输入值(不包括代码中的键),如下所示:
{ "name": "hello, world" }
以下是不同操作的示例格式:
添加或更新:
[
{
"op": "add",
"path": "/nodes/my-key",
"value": { "name": "hello, world" }
}
]
移除:
[
{
"op": "remove",
"path": "/nodes/my-key"
}
]
替换:这实际上类似于现有密钥的 add
。
[
{
"op": "replace",
"path": "/nodes/my-key",
"value": { "name": "hello, world" }
}
]
复制:
[
{
"op": "copy",
"from": "/nodes/my-existing-key",
"path": "/nodes/my-key"
}
]
移动:
[
{
"op": "move",
"from": "/nodes/my-existing-key",
"path": "/nodes/my-key"
}
]
注意:字典的路径格式要求字典属性为非空 。否则,该路径将被视为不存在,并会抛出一条错误消息,如下所示:
... the target location specified by path '/nodes/my-key' was not found
使用代码中使用的格式,将设置整个字典 属性。这就是为什么总是保留一个条目(最后一个条目覆盖所有其他条目,包括现有条目)。有了这个注意,你应该确保你的字典 属性 首先被初始化,像这样:
if(trie.Nodes == null){
trie.Nodes = new Dictionary<string, TrieNode>();
}
patchDoc.ApplyTo(trie, ModelState);
关于字典键类型:
在您的示例中,键类型是 string
,但它可以是任何类型,只要您有关联的 TypeConverter
即可使该类型正常工作。例如:它可以是 int
所以你可以正常使用 int 键,它可以是 DateTime
所以你可以使用像 yyyy-MM-dd
这样的键格式(在路径中使用)...
我有以下环境和 .NET Core 版本
.NET SDK (reflecting any global.json):
Version: 5.0.100
Commit: 5044b93829
Runtime Environment:
OS Name: Mac OS X
OS Version: 11.0
OS Platform: Darwin
RID: osx.11.0-x64
Base Path: /usr/local/share/dotnet/sdk/5.0.100/
使用以下代码和端点。
public class Trie
{
public string Id { get; set; }
public Dictionary<string, TrieNode> Nodes { get; set; }
}
public class TrieNode
{
public string Name { get; set; }
}
public async Task<IActionResult> Patch(string id, [FromBody] JsonPatchDocument<Trie> patchDoc)
{
var trie = [get from database]
patchDoc.ApplyTo(trie, ModelState);
}
当我使用以下操作时:
[
{
"op": "add",
"path": "/nodes/-", "value": { "/": { "name": "hello, world" } }
}
]
一个项目被添加到字典中是这样的:
"Nodes": {
"-": {
"Name": null
}
}
如果我对操作使用以下语法
[
{
"op": "add",
"path": "/nodes", "value": { "/": { "name": "hello, world" } }
}
]
项目是这样添加的:
"Nodes": {
"/": {
"Name": "hello, world"
}
}
但是当我尝试使用另一个键添加新项目时:
[
{
"op": "add",
"path": "/nodes", "value": { "/my-key": { "name": "hello, world" } }
}
]
该项 未 添加,它替换了第一个条目,因此结果如下所示:
"Nodes": {
"/my-key": {
"Name": "hello, world"
}
}
如何添加、删除、替换、复制、移动 Dictionary
您使用的格式将设置整个 属性 值(到仅包含一个条目的字典)。这就是为什么您看到它已添加但未更新的原因。
对于通过密钥更新条目,看起来这在任何地方都没有记录。更新密钥(添加或更新现有密钥)的实际语法如下所示:
/path-to-dictionary/string-key
以上路径也针对 remove
的现有条目。
然后 value
应该只是输入值(不包括代码中的键),如下所示:
{ "name": "hello, world" }
以下是不同操作的示例格式:
添加或更新:
[
{
"op": "add",
"path": "/nodes/my-key",
"value": { "name": "hello, world" }
}
]
移除:
[
{
"op": "remove",
"path": "/nodes/my-key"
}
]
替换:这实际上类似于现有密钥的 add
。
[
{
"op": "replace",
"path": "/nodes/my-key",
"value": { "name": "hello, world" }
}
]
复制:
[
{
"op": "copy",
"from": "/nodes/my-existing-key",
"path": "/nodes/my-key"
}
]
移动:
[
{
"op": "move",
"from": "/nodes/my-existing-key",
"path": "/nodes/my-key"
}
]
注意:字典的路径格式要求字典属性为非空 。否则,该路径将被视为不存在,并会抛出一条错误消息,如下所示:
... the target location specified by path '/nodes/my-key' was not found
使用代码中使用的格式,将设置整个字典 属性。这就是为什么总是保留一个条目(最后一个条目覆盖所有其他条目,包括现有条目)。有了这个注意,你应该确保你的字典 属性 首先被初始化,像这样:
if(trie.Nodes == null){
trie.Nodes = new Dictionary<string, TrieNode>();
}
patchDoc.ApplyTo(trie, ModelState);
关于字典键类型:
在您的示例中,键类型是 string
,但它可以是任何类型,只要您有关联的 TypeConverter
即可使该类型正常工作。例如:它可以是 int
所以你可以正常使用 int 键,它可以是 DateTime
所以你可以使用像 yyyy-MM-dd
这样的键格式(在路径中使用)...