2013-04-03 19 views
9

Data la seguente json:Deserialize matrice di coppie di valori chiave utilizzando Json.NET

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

che fa parte di un albero grande, come posso deserializzare i "dati" in proprietà:

List<MyCustomClass> Data { get; set; } 

o

List<KeyValuePair> Data { get; set; } 

o

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

utilizzando Json.NET? Entrambe le versioni funzioneranno (preferisco l'elenco di MyCustomClass). Ho già una classe che contiene altre proprietà, come questo:

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

dove "myCustomClass" dovrebbe includere solo due proprietà (Chiave e Valore). Ho notato che esiste una classe KeyValuePairConverter che sembra farebbe ciò di cui ho bisogno, ma non sono riuscito a trovare un esempio su come usarlo. Grazie.

risposta

16

Il modo più semplice è array deserialize di coppie chiave-valore a 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); 
} 
 

Ma se avete bisogno deserializzare che per la propria classe, può essere sguardi del genere:

 

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

     } 
    } 
} 
 

Vedi che io khow che Value è string e chiamo il metodo ToString(), ci può essere un'altra classe complessa.

+1

La lista di dizionari opere; grazie per quello Dato che il cambiamento che sto cercando di fare è parte di una libreria più grande, sto cercando di evitare di dover scrivere l'inizializzazione dell'oggetto personalizzato. Sto cercando di scrivere un convertitore personalizzato per la mia classe (SomeData2 nel tuo esempio). Se non riesco a farlo funzionare, userò il tuo metodo List of Dictionary. Grazie. – pbz

+0

Grazie mille per questa risposta. Stavo avendo lo stesso tipo di JSON con array con valore chiave. Ho appena usato public IEnumerable > Data {get; impostato; } per quel campo e ha funzionato come charme .. tutto il mio json è stato analizzato bene! .. – maths

1

ho finito per fare questo:

[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; } 
} 
Problemi correlati