Cargó el Json en una cadena, lo deserializó en una dinámica, ejecutó un foreach a través de él y lo agregó a una Lista con ResFiles en él.
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)); }
Estoy tratando de deserializar un archivo Json en C# con la biblioteca Json de Newtonsoft.
Los archivos tienen el nombre de su hash, no el nombre real del archivo y quiero cambiarles el nombre a los nombres correctos, así:
10a54fc66c8f479bb65c8d39c3b62265ac82e742 >> archivo_1.ext
El archivo 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 } } }He intentado deserializar con esto:
static void loadJson() { using (StreamReader reader = new StreamReader(jsonPath)) { string json = reader.ReadToEnd(); dynamic files = JsonConvert.DeserializeObject(json); } }La deserialización en sí funciona, pero no sé cómo recorrerlos.
También he intentado hacer esto:
class ResFile { public string name; public string hash; public int size; }Y de alguna manera fuerce la deserialización para usar esto, pero no funcionó, por supuesto.
De acuerdo con su json de muestra, sus clases serían:
public class ResFile { public string hash { set; get; } public int size { set; get; } } public class ResRoot { public Dictionary<string, ResFile> Files { set; get; } }Puede deserializar como
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); }Siga las convenciones de C# y no exponga las variables miembro como públicas ni comience los nombres de propiedad con minúsculas. Para hacer que sus objetos convencionales sean deserializables, puede usar los atributos System.Runtime.Serialization DataContract y DataMember. DataContract indica que un objeto de este tipo es serializable y DataMember se usa para especificar el nombre de serialización de una propiedad.
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; } }Y aquí está la deserialización:
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); }Los nombres de propiedad serializados también deben ser más cortos para un mejor rendimiento. Un ejemplo:
[DataMember(Name="src")] public string SourcePath { get; set; }