在 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 这样的键格式(在路径中使用)...