web-dev-qa-db-fra.com

Désérialiser Json à partir d'un fichier en C #

J'ai réussi à trouver une solution sans supprimer les chemins des clés.
Merci pour l'aide les gars, et aussi en soulignant les problèmes, je l'apprécie vraiment! :)

Chargé le Json à une chaîne, désérialisé en une dynamique, parcouru une chaîne avant et ajouté à une liste contenant ResFiles.

static void loadJson()
{
    List<ResFile> fileList = new List<ResFile>();
    string jsonString = File.ReadAllText(jsonPath);
    dynamic files = JsonConvert.DeserializeObject(jsonString);

    foreach (var f in files.objects)
        fileList.Add(new ResFile(f.Name, f.Value.hash.ToString(), (int)f.Value.size.Value));
}




J'essaie de désérialiser un fichier Json en C # avec la bibliothèque Json de Newtonsoft.
Les fichiers sont nommés d'après son hachage, pas le nom de fichier réel et je veux les renommer en noms propres, donc comme ceci:
10a54fc66c8f479bb65c8d39c3b62265ac82e742 >> fichier_1.ext

Le fichier Json:

{
  "files": {
    "file_1.ext": {
      "hash": "10a54fc66c8f479bb65c8d39c3b62265ac82e742",
      "size": 8112
    },
    "file_2.ext": {
      "hash": "14cfb2f24e7d91dbc22a2a0e3b880d9829320243",
      "size": 7347
    },
    "file_3.ext": {
      "hash": "bf7fadaf64945f6b31c803d086ac6a652aabef9b",
      "size": 3838
    },
    "file_4.ext": {
      "hash": "48f7e1bb098abd36b9760cca27b9d4391a23de26",
      "size": 6905
    }
  }
}

J'ai essayé de désérialiser avec ceci:

static void loadJson()
{
    using (StreamReader reader = new StreamReader(jsonPath))
    {
        string json = reader.ReadToEnd();
        dynamic files = JsonConvert.DeserializeObject(json);
    }
}

La désérialisation elle-même fonctionne, mais je ne sais pas comment les parcourir en boucle.

J'ai aussi essayé de faire ça:

class ResFile
{
    public string name;
    public string hash;
    public int size;
}

Et forcer la désérialisation à l'utiliser, mais cela n'a pas fonctionné bien sûr.

7
David Dosa

Selon votre exemple de json, vos cours seraient:

public class ResFile
{
    public string hash { set; get; }
    public int size { set; get; }
}

public class ResRoot
{
    public Dictionary<string, ResFile> Files { set; get; }
}

Vous pouvez désérialiser en tant que

var res = JsonConvert.DeserializeObject<ResRoot>(File.ReadAllText(filename));

foreach(var f in res.Files)
{
    Console.WriteLine("Name={0} Size={1}", f.Key, f.Value.size);
}
19
EZI

Suivez les conventions C # et n'exposez pas les variables de membre en tant que noms de propriété publics ou de début avec des minuscules. Pour rendre vos objets conventionnels désérialisables, vous pouvez utiliser les attributs System.Runtime.Serialization DataContract et DataMember. DataContract indique qu'un objet de ce type est sérialisable et DataMember est utilisé pour spécifier le nom de sérialisation d'une propriété.

class ResFile
{
    [DataMember(Name = "name")]
    public string Name { get; set; } 

    [DataMember(Name = "hash")]
    public string Hash { get; set; } 

    [DataMember(Name = "size")]
    public int Size { get; set; }

    public ResFile () { }
}

[DataContract]
class ResFileCollection
{
    [DataMember(Name ="files")]
    public Dictionary<string, ResFile> Files { get; set; }
}

Et voici la désérialisation:

string json = File.ReadAllText("data.json");
        var files = JsonConvert.DeserializeObject<ResFileCollection>(json);
        foreach(KeyValuePair<string, ResFile> f in files.Files)
        {
            Console.WriteLine("{0} {1} {2}", f.Key, f.Value.Name, f.Value.Hash);
        }

Les noms de propriété sérialisés doivent également être plus courts pour de meilleures performances. Un exemple:

[DataMember(Name="src")]
public string SourcePath { get; set; }
1
Alexander Ivanov