serialize newtonsoft jobject example create c# json.net

c# - newtonsoft - ¿Cómo se agrega un JToken a JObject?



newtonsoft json documentation (3)

Estoy tratando de agregar un objeto JSON de un texto a un archivo JSON existente usando JSON.Net. Por ejemplo, si tengo los datos JSON de la siguiente manera:

{ "food": { "fruit": { "apple": { "colour": "red", "size": "small" }, "orange": { "colour": "orange", "size": "large" } } } }

He estado tratando de hacer esto así:

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);

Pero esto da el error: "Newtonsoft.Json.Linq.JProperty cannot have multiple values."

De hecho, he intentado de diferentes maneras, pero parece que no puedo llegar a ninguna parte. En mi ejemplo, lo que realmente quiero hacer es agregar el nuevo elemento a "fruta". Por favor, avíseme si hay una mejor manera de hacerlo o una biblioteca más simple de usar.


Creo que te estás confundiendo acerca de qué puede contener qué en JSON.Net.

  • A JToken es una representación genérica de un valor JSON de cualquier tipo. Podría ser una cadena, un objeto, una matriz, una propiedad, etc.
  • Un JProperty es un solo valor JToken emparejado con un nombre. Solo se puede agregar a JObject y su valor no puede ser otro JProperty .
  • Un JObject es una colección de JProperties . No puede contener ningún otro tipo de JToken directamente.

En su código, está intentando agregar un JObject (el que contiene los datos "banana") a un JProperty ("orange") que ya tiene un valor (un JObject contiene {"colour":"orange","size":"large"} ). Como viste, esto dará como resultado un error.

Lo que realmente quieres hacer es agregar un JProperty llamado "banana" al JObject que contiene las otras frutas JProperties . Aquí está el código revisado:

JObject foodJsonObj = JObject.Parse(jsonText); JObject fruits = foodJsonObj["food"]["fruit"] as JObject; fruits.Add("banana", JObject.Parse(@"{""colour"":""yellow"",""size"":""medium""}"));


Solo agregue. .First a su bananaToken debería hacerlo:
foodJsonObj["food"]["fruit"]["orange"].Parent.AddAfterSelf(bananaToken .First );
.First básicamente pasa del { para convertirlo en JProperty lugar de JToken .

@Brian Rogers, gracias, olvidé el .Parent . Editado


TL; DR: Debería agregar una JProperty a JObject. Sencillo. La consulta de índice devuelve un JValue, así que averigua cómo obtener el JProperty en su lugar :)

La respuesta aceptada no responde la pregunta como parece. ¿Qué sucede si quiero agregar específicamente JProperty después de uno específico? Primero, comencemos con terminologías que realmente me hicieron pensar.

  • JToken = La madre de todos los demás tipos. Puede ser A JValue, JProperty, JArray o JObject. Esto es para proporcionar un diseño modular al mecanismo de análisis sintáctico.
  • JValue = cualquier tipo de valor Json (string, int, boolean).
  • JProperty = cualquier JValue o JContainer (ver a continuación) emparejado con un nombre (identificador) . Por ejemplo, "name":"value" .
  • JContainer = La madre de todos los tipos que contienen otros tipos (JObject, JValue).
  • JObject = un tipo JContainer que contiene una colección de JProperties
  • JArray = un tipo JContainer que contiene una colección JValue o JContainer.

Ahora, cuando consulta el elemento Json utilizando el índice [], obtiene el JToken sin el identificador, que podría ser un JContainer o un JValue (requiere conversión), pero no puede agregar nada después de él, porque es solo un valor. Puede cambiarlo por sí mismo, consultar valores más profundos, pero no puede agregar nada después de eso, por ejemplo.

Lo que realmente desea obtener es la propiedad como un todo, y luego agregue otra propiedad después de ella como lo desee. Para esto, usas JOjbect.Property("name") , y luego creas otro JProperty de tu deseo y luego lo agregas después de esto usando el método AddAfterSelf . Has terminado entonces.

Para más información: http://www.newtonsoft.com/json/help/html/ModifyJson.htm

Este es el código que modifiqué.

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); } } }