我正在尝试使用JSON.Net将JSON对象从某些文本添加到现有的JSON文件中。例如,如果我有如下的JSON数据:
{
"food": {
"fruit": {
"apple": {
"colour": "red",
"size": "small"
},
"orange": {
"colour": "orange",
"size": "large"
}
}
}
}
我一直试图这样做:
var foodJsonObj = JObject.Parse(jsonText);
var bananaJson = JObject.Parse(@"{ ""banana"" : { ""colour"": ""yellow"", ""size"": ""medium""}}");
var bananaToken = bananaJson as JToken;
foodJsonObj["food"]["fruit"]["orange"].AddAfterSelf(bananaToken);
但这会产生错误:"Newtonsoft.Json.Linq.JProperty cannot have multiple values."
我实际上尝试了几种不同的方法,但似乎无法到达任何地方。在我的例子中,我真正想要做的是将新项添加到“fruit”。如果有更好的方法或更简单的库可供使用,请告诉我。
答案 0 :(得分:118)
我认为你对JSON.Net中的内容感到困惑。
JToken
是任何类型的JSON值的通用表示。它可以是字符串,对象,数组,属性等。JProperty
是与名称配对的单个JToken
值。它只能添加到JObject
,其值不能是另一个JProperty
。JObject
是JProperties
的集合。它不能直接保留任何其他类型的JToken
。在您的代码中,您试图将JObject
(包含“香蕉”数据的数据)添加到已经具有值{{1}的JProperty
(“橙色”)包含JObject
)。如您所见,这将导致错误。
您真正想要做的是向{"colour":"orange","size":"large"}
添加名为“banana”的JProperty
,其中包含其他水果JObject
。以下是修订后的代码:
JProperties
答案 1 :(得分:30)
TL; DR:您应该将一个JProperty添加到JObject。简单。索引查询返回一个JValue,因此请弄清楚如何获取JProperty:)
接受的答案似乎没有回答这个问题。如果我想在特定的一个之后专门添加JProperty怎么办?首先,让我们从真正让我头脑清醒的术语开始。
"name":"value"
。现在,当您使用index []查询Json项时,您将获得没有标识符的JToken,它可能是JContainer或JValue(需要转换),但您不能在它之后添加任何内容,因为它只是一个值。您可以自行更改,查询更深的值,但不能在其后添加任何内容。
您实际想要的是整个属性,然后根据需要添加其他属性。为此,您使用JOjbect.Property("name")
,然后根据需要创建另一个JProperty,然后使用AddAfterSelf
方法在此之后添加它。那你完成了。
了解更多信息:http://www.newtonsoft.com/json/help/html/ModifyJson.htm
这是我修改的代码。
public class Program
{
public static void Main()
{
try
{
string jsonText = @"
{
""food"": {
""fruit"": {
""apple"": {
""colour"": ""red"",
""size"": ""small""
},
""orange"": {
""colour"": ""orange"",
""size"": ""large""
}
}
}
}";
var foodJsonObj = JObject.Parse(jsonText);
var bananaJson = JObject.Parse(@"{ ""banana"" : { ""colour"": ""yellow"", ""size"": ""medium""}}");
var fruitJObject = foodJsonObj["food"]["fruit"] as JObject;
fruitJObject.Property("orange").AddAfterSelf(new JProperty("banana", fruitJObject));
Console.WriteLine(foodJsonObj.ToString());
}
catch (Exception ex)
{
Console.WriteLine(ex.GetType().Name + ": " + ex.Message);
}
}
}
答案 2 :(得分:5)
只需将 .First
添加到bananaToken
即可:
foodJsonObj["food"]["fruit"]["orange"].Parent.AddAfterSelf(bananaToken .First
);
.First
基本上超越 {
,使其成为 JProperty
,而不是 JToken
即可。
.Parent
。编辑