2016-04-21 19 views
3

Ich möchte ein zweidimensionales Array zu einer Sammlung von .net-Objekten deserialisieren. Der Grund dafür ist, dass die Array-Syntax für meinen Benutzer einfacher ist, in einer Eingabedatei zu arbeiten. Daher möchte ich die Indizes der Arrays nur bestimmten Eigenschaften meines Zieltyps zuordnen.JSON-Deserialisierung - Array-Indizes zu Eigenschaften mit JSON.NET zuordnen

E.G. Mit:

[ 
    ["John", "Smith", "23"], 
    ["Paula", "Martin", "54] 
] 

würde ich zwei Instanzen einer Person erhalten:

public class Person { 
    public string First {get;set;} 
    public string Last {get;set;} 
    public string Age {get;set;} 
} 

wobei der Index 0 einen inneren Array abbildet First, Index 1 Karten Last und Index 2 Karten zu Age;

Gibt es eine Möglichkeit, Json.NET zu erweitern, so dass ich die Zuordnung während der Deserialisierung durchführen kann, so dass die Implementierungsdetails verborgen sind? Ich habe mit einer benutzerdefinierten JsonConverter gespielt, aber ich habe nicht viel Information darüber gefunden, wie man es benutzt.

Edit: Insbesondere, ich bin nicht sicher, ob JsonConverter das Richtige ist, zu verwenden, und ich habe Probleme, herauszufinden, wie CanConvert zu implementieren und wie die Parameter der ReadJson Methode übergeben können.

+0

Sieht aus wie etwas, Ich würde versuchen zu tun - aber ich würde vorschlagen, dass am Ende Sie nur mit Standard-Json verwenden. Die Feldnamen müssen für jede 'Person' wiederholt werden, aber es ist ein kleiner Preis. – Patrick

Antwort

6

Sie können dies mit einem JsonConverter tun. Ein einfacher Konverter für diesen Zweck wäre:

public class PersonConverter : JsonConverter 
{ 
    public override bool CanConvert(Type objectType) 
    { 
     return objectType == typeof(Person); 
    } 

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) 
    { 
     if (reader.TokenType == JsonToken.Null) 
      return null; 
     var array = JArray.Load(reader); 
     var person = (existingValue as Person ?? new Person()); 
     person.First = (string)array.ElementAtOrDefault(0); 
     person.Last = (string)array.ElementAtOrDefault(1); 
     person.Age = (string)array.ElementAtOrDefault(2); 
     return person; 
    } 

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) 
    { 
     var person = (Person)value; 
     serializer.Serialize(writer, new[] { person.First, person.Last, person.Age }); 
    } 
} 

Dann Sie es Ihrer Klasse anwenden können:

[JsonConverter(typeof(PersonConverter))] 
public class Person 
{ 
    public string First { get; set; } 
    public string Last { get; set; } 
    public string Age { get; set; } 
} 

Oder es in Einstellungen verwenden:

var settings = new JsonSerializerSettings { Converters = new [] { new PersonConverter() } }; 
var list = JsonConvert.DeserializeObject<List<Person>>(json, settings); 
+0

Dies scheint, als ob es auf der richtigen Spur ist, aber es scheint nur ein einzelnes Person-Array, nicht ein Array von Person-Arrays zu behandeln. Ich werde als eine Antwort für die Bestätigung, dass ein JsonConverter es tun kann, markieren. Sehen Sie meine Antwort für die Implementierung, die ich gefunden habe. Bitte lassen Sie mich wissen, wenn Sie irgendwelche Probleme damit sehen. – xr280xr

0
public override bool CanConvert(Type objectType) 
    { 
     if (objectType == typeof(List<Person>)) return true; 

     return false; 
    } 

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) 
    { 
     List<Person> persons = new List<Person>(); 

     JArray personsArray = (JArray)serializer.Deserialize(reader); 

     foreach (var personArray in personsArray.Children<JArray>()) 
     { 
      persons.Add(new Person() { 
         First = personArray[0].Value<string>(), 
         Last = personArray[1].Value<string>(), 
         Age = personArray[2].Value<string>() 
         }); 
     } 

     return persons; 
    } 
Verwandte Themen