89 votes

Comment ajouter un JToken à un JObject ?

J'essaie d'ajouter un objet JSON à partir d'un texte à un fichier JSON existant en utilisant JSON.Net. Par exemple, si j'ai les données JSON comme ci-dessous :

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

J'ai essayé de faire ça comme ça :

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

Mais cela donne l'erreur : "Newtonsoft.Json.Linq.JProperty cannot have multiple values."

J'ai essayé plusieurs méthodes différentes, mais je n'arrive à rien. Dans mon exemple, ce que je veux vraiment faire, c'est ajouter le nouvel élément à "fruit". Veuillez me faire savoir s'il existe une meilleure façon de procéder ou une bibliothèque plus simple à utiliser.

148voto

Brian Rogers Points 12160

Je pense que vous vous trompez sur ce qui peut contenir quoi dans JSON.Net.

  • A JToken est une représentation générique d'une valeur JSON de n'importe quel type. Il peut s'agir d'une chaîne, d'un objet, d'un tableau, d'une propriété, etc.
  • A JProperty est un seul JToken valeur associée à un nom. Il ne peut être ajouté qu'à un JObject et sa valeur ne peut pas être une autre JProperty .
  • A JObject est une collection de JProperties . Il ne peut contenir aucun autre type de JToken directement.

Dans votre code, vous essayez d'ajouter un JObject (celle qui contient les données "banane") à une JProperty ("orange") qui a déjà une valeur (un JObject contenant {"colour":"orange","size":"large"} ). Comme vous l'avez vu, cela entraînera une erreur.

Ce que vous voulez vraiment faire, c'est ajouter un JProperty appelé "banane" à la JObject qui contient l'autre fruit JProperties . Voici le code révisé :

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

41voto

Ghasan Points 553

TL;DR : Vous devez ajouter une JProperty à un JObject. C'est simple. La requête d'index renvoie une JValue, alors trouvez comment obtenir la JProperty à la place :)


La réponse acceptée ne répond pas à la question comme elle le semble. Que faire si je veux ajouter spécifiquement une JProperty après une autre ? Tout d'abord, commençons par les terminologies qui m'ont vraiment fait tourner la tête.

  • JToken = La mère de tous les autres types. Il peut être une JValue, une JProperty, un JArray ou un JObject. Ceci afin de fournir une conception modulaire au mécanisme d'analyse syntaxique.
  • JValue = tout type de valeur Json (string, int, boolean).
  • JProperty = n'importe quelle JValue ou JContainer (voir ci-dessous) jumelée à un nom (identifiant) . Par exemple "name":"value" .
  • JContainer = La mère de tous les types qui contiennent d'autres types (JObject, JValue).
  • JObject = un type de JContainer qui contient une collection de JProperties.
  • JArray = un type de JContainer qui contient une collection JValue ou JContainer.

Maintenant, lorsque vous interrogez un élément Json en utilisant l'index [], vous obtenez le JToken sans l'identifiant, qui peut être un JContainer ou une JValue (nécessite un casting), mais vous ne pouvez rien ajouter après, parce que c'est seulement une valeur. Vous pouvez la modifier elle-même, demander des valeurs plus profondes, mais vous ne pouvez rien ajouter après elle, par exemple.

Ce que vous voulez en fait, c'est obtenir la propriété dans son ensemble, puis ajouter une autre propriété après elle, comme vous le souhaitez. Pour cela, vous utilisez JOjbect.Property("name") puis créez une autre JProperty de votre choix et ajoutez-la après celle-ci en utilisant AddAfterSelf méthode. Vous avez alors terminé.

Pour plus d'informations : http://www.newtonsoft.com/json/help/html/ModifyJson.htm

Voici le code que j'ai modifié.

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

5voto

RepDbg Points 51

Il suffit d'ajouter .First à votre bananaToken devrait le faire :
foodJsonObj["food"]["fruit"]["orange"].Parent.AddAfterSelf(bananaToken .First);
.First passe essentiellement devant le { pour en faire un JProperty au lieu d'un JToken .

@Brian Rogers, Merci j'ai oublié la .Parent . Publié sur

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X