C# 添加JToken时,获取错误Newtonsoft.Json.Linq.JProperty不能有多个值
我有以下附加信息的结构,其中我需要更新结构中一个令牌的值。数据是一个jtoken数组,其父级名为“additionalFields”,如下所示:C# 添加JToken时,获取错误Newtonsoft.Json.Linq.JProperty不能有多个值,c#,json.net,C#,Json.net,我有以下附加信息的结构,其中我需要更新结构中一个令牌的值。数据是一个jtoken数组,其父级名为“additionalFields”,如下所示: {{"additionalFields": [ { "name": "NAME1", "value": "VALUE1" }, { "name": "NAME2", "value": &quo
{{"additionalFields":
[
{ "name": "NAME1", "value": "VALUE1" },
{ "name": "NAME2", "value": "VALUE2" },
{ "name": "NAME3", "value": "VALUE3" },
{ "name": "NAME4", "value": "VALUE4" }
]}
我正在尝试更新其中一个令牌的值,例如将VALUE1更改为VALUE10
一旦我找到了令牌,我需要更新我的代码,并按如下方式删除它
additionalField.Remove();
additionalFields.AddAfterSelf(updatedToken);
然后,我使用以下函数创建一个新令牌来替换我已删除的令牌(包含新值)
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}\"}}";
}
然后我添加新的令牌,如下所示
additionalField.Remove();
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!!
}
}
foreach(附加字段中的var附加字段)
{
//这是我们要找的钥匙吗?
var-keyToken=additionalField.First;
如果(keyToken?.First==null)继续;
if(string.Equals(keyToken.First.ToString(),“newname”,StringComparison.CurrentCultureIgnoreCase))
{
//删除当前令牌
additionalField.Remove();
//添加更新的令牌
var updatedToken=CreateNewToken(“newname”、“newvalue”);
additionalFields.AddAfterSelf(updatedToken);我可以在这里重现您的问题:
出什么事了
additionalFields
引用包含name
和value
jproperty的JObject的JArray。您正在该JArray中循环,试图找到第一个具有name
属性且具有特定值的JObject,当您找到它时,尝试用一个全新的JObject替换该JObject。您成功了吗成功地从JArray中删除旧JObject,但是当您执行插入新JObject的AddAfterSelf
操作时,您引用的是附加字段
(复数)而不是附加字段
(单数)。回想一下,additionalFields
是JArray。因此,您的意思是要在数组之后添加新的JObject。数组的父级是一个名为additionalFields
的JPProperty。JPProperty只能有一个值,因此AddAfterSelf
失败,出现错误
如何修复代码
我认为您打算做的是additionalField.AddAfterSelf(updatetoken)
。但是,这也会失败,原因不同:此时您已经从JArray中删除了附加字段
,因此它不再具有父上下文。在删除试图插入的项之前,您需要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;
}
小提琴:
更简单的方法
要完成此任务,您似乎要经历很多困难。您可以使用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";
}
工作演示:请展示所有相关代码。添加了额外的代码,希望能更好地了解问题哇,这是对我问题的精彩回答,您已经清楚地解释了我试图迭代JSON对象时的错误理解。非常感谢您花时间如此清楚地解释这一切,我真的很抱歉珍爱它。别担心,很高兴我能帮上忙!