2013-04-03 16 views
9

mit dem folgenden json:Deserialize Array von Schlüsselwertpaaren mittels Json.NET

[ {"id":"123", ... "data":[{"key1":"val1"}, {"key2":"val2"}], ...}, ... ] 

, die Teil eines größeren Baum ist, wie kann ich deserialisiert "Daten" Eigenschaft in:

List<MyCustomClass> Data { get; set; } 

oder

List<KeyValuePair> Data { get; set; } 

oder

Dictionary<string, string> Data { get; set; } 

mit Json.NET? Jede Version wird es tun (ich bevorzuge jedoch List of MyCustomClass). Ich habe bereits eine Klasse, die andere Eigenschaften enthält, wie folgt aus:

public class SomeData 
{ 
    [JsonProperty("_id")] 
    public string Id { get; set; } 
    ... 
    public List<MyCustomClass> Data { get; set; } 
} 

wo „myCustomClass“ umfassen würde nur zwei Eigenschaften (Schlüssel und Wert). Ich habe bemerkt, dass es eine KeyValuePairConverter-Klasse gibt, die klingt, als würde sie tun, was ich brauche, aber ich konnte kein Beispiel finden, wie ich sie benutzen könnte. Vielen Dank.

Antwort

16

Der einfachste Weg ist deserialize Array von Schlüssel-Wert-Paare IDictionary<string, string>:

 

public class SomeData 
{ 
    public string Id { get; set; } 

    public IEnumerable<IDictionary<string, string>> Data { get; set; } 
} 

private static void Main(string[] args) 
{ 
    var json = "{ \"id\": \"123\", \"data\": [ { \"key1\": \"val1\" }, { \"key2\" : \"val2\" } ] }"; 

    var obj = JsonConvert.DeserializeObject<SomeData>(json); 
} 
 

Aber wenn du das eigene Klasse brauchen deserialisieren, kann es sieht aus wie das sein:

 

public class SomeData2 
{ 
    public string Id { get; set; } 

    public List<SomeDataPair> Data { get; set; } 
} 

public class SomeDataPair 
{ 
    public string Key { get; set; } 

    public string Value { get; set; } 
} 

private static void Main(string[] args) 
{ 
    var json = "{ \"id\": \"123\", \"data\": [ { \"key1\": \"val1\" }, { \"key2\" : \"val2\" } ] }"; 

    var rawObj = JObject.Parse(json); 

    var obj2 = new SomeData2 
    { 
     Id = (string)rawObj["id"], 
     Data = new List<SomeDataPair>() 
    }; 

    foreach (var item in rawObj["data"]) 
    { 
     foreach (var prop in item) 
     { 
      var property = prop as JProperty; 

      if (property != null) 
      { 
       obj2.Data.Add(new SomeDataPair() { Key = property.Name, Value = property.Value.ToString() }); 
      } 

     } 
    } 
} 
 

Sehen Sie, dass ich khow, dass Valuestring ist und ich ToString() Methode aufrufen, kann es eine andere komplexe Klasse geben.

+1

Die Liste der Wörterbücher Werke; Dank dafür. Da die Änderung, die ich versuche zu machen, Teil einer größeren Bibliothek ist, versuche ich zu vermeiden, eine benutzerdefinierte Objektinitialisierung schreiben zu müssen. Ich bin dabei, einen benutzerdefinierten Konverter für meine Klasse zu schreiben (SomeData2 in Ihrem Beispiel). Wenn ich es nicht zum Laufen kriege, dann benutze ich Ihre List of Dictionary Methode. Vielen Dank. – pbz

+0

Vielen Dank für diese Antwort. Ich hatte die gleiche Art von JSON mit Array mit Schlüsselwert. Ich habe nur öffentliche IEnumerable verwendet > Data {get; einstellen; } für dieses Feld und arbeitete wie Charme .. mein ganzer JSON wurde fein geparst! .. – maths

1

landete ich dies zu tun:

[JsonConverter(typeof(MyCustomClassConverter))] 
public class MyCustomClass 
{ 
    internal class MyCustomClassConverter : JsonConverter 
    { 
    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) 
    { 
     throw new NotImplementedException(); 
    } 

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) 
    { 
     JObject jObject = JObject.Load(reader); 

     foreach (var prop in jObject) 
     { 
     return new MyCustomClass { Key = prop.Key, Value = prop.Value.ToString() }; 
     } 

     return null; 
    } 

    public override bool CanConvert(Type objectType) 
    { 
     return typeof(MyCustomClass).IsAssignableFrom(objectType); 
    } 
    } 

    public string Key { get; set; } 
    public string Value { get; set; } 
} 
Verwandte Themen