我有以下附加信息结构,我需要更新结构中其中一个标记的值。数据是一个 JToken 数组,其父级名为“additionalFields”,如下所示:
{{"additionalFields":
[
{ "name": "NAME1", "value": "VALUE1" },
{ "name": "NAME2", "value": "VALUE2" },
{ "name": "NAME3", "value": "VALUE3" },
{ "name": "NAME4", "value": "VALUE4" }
]}
我正在尝试更新其中一个 token 的值,例如将 VALUE1 更改为 VALUE10。
找到 token 后,我需要更新代码将其删除,如下所示。
additionalField.Remove();
然后,我使用以下函数创建一个新 token 来替换我已删除的 token (包含新值)。
public static JToken CreateNewToken(string name, string value)
{
var stringToken = CreateNewStringToken(name, value);
var token = JToken.Parse(stringToken);
return (JToken) token;
}
private static string CreateNewStringToken(string name, string value)
{
return $"{{\"name\":\"{name}\",\"value\":\"{value}\"}}";
}
然后,我按如下方式添加新 token 。
additionalFields.AddAfterSelf(updatedToken);
把它们放在一起我们有以下内容
foreach (var additionalField in additionalFields)
{
//is this the key we are looking for?
var keyToken = additionalField.First;
if (keyToken?.First == null) continue;
if (string.Equals(keyToken.First.ToString(), "newname", StringComparison.CurrentCultureIgnoreCase))
{
//remove the current token
additionalField.Remove();
//add the updated token
var updatedToken = CreateNewToken("newname", "newvalue");
additionalFields.AddAfterSelf(updatedToken); <-- error occurs here!!
}
}
但是添加 token 后我收到以下错误
Newtonsoft.Json.Linq.JProperty 不能有多个值
我可以在调试器中看到 token 已被删除(因为 token.Count 减少了 1),因此无法理解为什么我在添加替换 token 时遇到错误。
最佳答案
我能够在这里重现您的问题:https://dotnetfiddle.net/JIVCVB
出了什么问题
additionalFields
指的是包含name
和value
JProperties 的JObject 的JArray。您正在循环访问此 JArray,尝试查找第一个具有特定值的 name
属性的 JObject,当您找到它时,您会尝试用全新的 JObject 替换该 JObject。您成功从 JArray 中删除了旧 JObject,但是当您执行 AddAfterSelf
插入新 JObject 时,您引用的是 additionalFields
(复数)而不是 additionalField
(单数)。回想一下,additionalFields 是 JArray。所以你是说你想在数组之后添加新的JObject。该数组的父级是一个名为 additionalFields
的 JProperty。 JProperty 只能有一个值,因此 AddAfterSelf
失败并出现您看到的错误。
如何修复代码
我认为您打算做的是additionalField.AddAfterSelf(updatedToken)
。但是,由于不同的原因,这也会失败:此时您已经从 JArray 中删除了 additionalField
,因此它不再具有父上下文。在删除要插入的项目之前,您需要AddAfterSelf
。如果您解决了这个问题,您仍然会遇到另一个问题:完成替换后循环不会中断,因此您将在循环遍历集合时收到有关修改集合的错误。
以下是经过更正的相关代码部分:
if (string.Equals(keyToken.First.ToString(), "NAME1", StringComparison.CurrentCultureIgnoreCase))
{
//add the updated token
var updatedToken = CreateNewToken("newname", "newvalue");
additionalField.AddAfterSelf(updatedToken);
//remove the current token
additionalField.Remove();
// we found what we were looking for so no need to continue looping
break;
}
fiddle :https://dotnetfiddle.net/KcFsZc
更简单的方法
您似乎要克服很多困难才能完成这项任务。您可以使用 FirstOrDefault 来查找数组中要查找的对象,而不是循环。一旦找到它,您就不需要替换整个对象;您可以直接更新属性值。
方法如下:
var rootObject = JToken.Parse(json);
// Get a reference to the array of objects as before
var additionalFields = rootObject["additionalFields"];
// Find the object we need to change in the array
var additionalField = additionalFields.FirstOrDefault(f =>
string.Equals((string)f["name"], "NAME1", StringComparison.CurrentCultureIgnoreCase);
// if the object is found, update its properties
if (additionalField != null)
{
additionalField["name"] = "newname";
additionalField["value"] = "newvalue";
}
关于c# - 添加 JToken 时出现错误 Newtonsoft.Json.Linq.JProperty 不能有多个值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64915074/