web-dev-qa-db-fra.com

Analyser la chaîne JSON dans la liste <chaîne>

string json = "{\"People\":[{\"FirstName\":\"Hans\",\"LastName\":\"Olo\"}
                            {\"FirstName\":\"Jimmy\",\"LastName\":\"Crackedcorn\"}]}";

var obj = JObject.Parse(json);

List<string> first;
List<string> last;

foreach (var child in obj["People"].Children())
{
    var name = child.First()["countryName"].ToString();
    var two = child.First()["countryCode"].ToString();
    var three = child.First()["isoAlpha3"].ToString();

    countries.Add(name);
    twoCharCodes.Add(two);
    threeCharCodes.Add(three);

    Console.Write("Name:\t\t{0}\n2CharCode:\t{1}\n3CharCode:\t{2}\n\n", name, two, three);
}

Je cherche un moyen d'ajouter chaque valeur FirstName dans la première liste et la même chose avec les noms LastName et la dernière liste Quelle est la meilleure façon de s'y prendre?

Le code ci-dessus apparaît sur:

var name = child.First()["countryName"].ToString();

avec cette erreur:

 Cannot access child value on Newtonsoft.Json.Linq.JProperty

Aucun conseil?

6
ChangeJar

Cela semble être une mauvaise façon de le faire (créer deux listes corrélées), mais je suppose que vous avez vos raisons.

J'analyserais la chaîne JSON (qui a une faute de frappe dans votre exemple, il manque une virgule entre les deux objets) dans un objet fortement typé, puis j'utilise deux requêtes LINQ pour obtenir les deux listes.

void Main()
{
    string json = "{\"People\":[{\"FirstName\":\"Hans\",\"LastName\":\"Olo\"},{\"FirstName\":\"Jimmy\",\"LastName\":\"Crackedcorn\"}]}";

    var result = JsonConvert.DeserializeObject<RootObject>(json);

    var firstNames = result.People.Select (p => p.FirstName).ToList();
    var lastNames = result.People.Select (p => p.LastName).ToList();
}

public class Person
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
}

public class RootObject
{
    public List<Person> People { get; set; }
}
12
Craig W.

Puisque vous utilisez JSON.NET, personnellement, je choisirais la sérialisation afin que vous puissiez bénéficier du support Intellisense pour votre objet. Vous aurez besoin d'une classe qui représente votre structure JSON. Vous pouvez le construire à la main ou vous pouvez utiliser quelque chose comme json2csharp pour le générer pour vous:

par exemple.

public class Person
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
}

public class RootObject
{
    public List<Person> People { get; set; }
}

Ensuite, vous pouvez simplement appeler les méthodes de JsonConvert pour désérialiser le JSON en un objet:

RootObject instance = JsonConvert.Deserialize<RootObject>(json);

Ensuite, vous avez Intellisense:

var firstName = instance.People[0].FirstName;
var lastName = instance.People[0].LastName;
7
Kenneth K.

Je voulais poster ceci en tant que commentaire en tant que note latérale à la réponse acceptée, mais cela est un peu incertain . Donc, purement en tant que note latérale:

Si vous n'avez pas besoin des objets eux-mêmes et que vous souhaitez que votre projet soit débarrassé de toutes les classes inutilisées, vous pouvez analyser avec quelque chose comme:

var list = JObject.Parse(json)["People"].Select(el => new { FirstName = (string)el["FirstName"], LastName = (string)el["LastName"] }).ToList();

var firstNames = list.Select(p => p.FirstName).ToList();
var lastNames = list.Select(p => p.LastName).ToList();

Même si vous utilisez une classe de personnes fortement typée, vous pouvez toujours ignorer l'objet racine en créant une liste avec JObject.Parse(json)["People"].ToObject<List<Person>>() Bien entendu, si vous devez réutiliser les objets, il est préférable de les créer dès le début. Je voulais juste souligner l'alternative;)

0
Me.Name

J'utilise cette classe JSON Helper dans mes projets. Je l'ai trouvé sur le net il y a un an, mais j'ai perdu l'URL source. Je le colle donc directement depuis mon projet:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Runtime.Serialization.Json;
using System.IO;
using System.Text;
/// <summary>
/// JSON Serialization and Deserialization Assistant Class
/// </summary>
public class JsonHelper
{
    /// <summary>
    /// JSON Serialization
    /// </summary>
    public static string JsonSerializer<T> (T t)
    {
        DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(T));
        MemoryStream ms = new MemoryStream();
        ser.WriteObject(ms, t);
        string jsonString = Encoding.UTF8.GetString(ms.ToArray());
        ms.Close();
        return jsonString;
    }
    /// <summary>
    /// JSON Deserialization
    /// </summary>
    public static T JsonDeserialize<T> (string jsonString)
    {
        DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(T));
        MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(jsonString));
        T obj = (T)ser.ReadObject(ms);
        return obj;
    }
}

Vous pouvez l'utiliser comme suit: Créez les classes comme suggéré par Craig W.

Et puis désérialiser comme ça

RootObject root = JSONHelper.JsonDeserialize<RootObject>(json);
0
Aishwarya Shiva