2017-09-13 1 views
0

Je veux avoir deux méthodes d'essai passent:Désérialise cet objet avec Json.NET

[TestMethod] 
public void TestDeserializationSingleArray() 
{ 
    // metaGrids is an array of arrays. 
    var data = @"{ 
        ""metaGrids"": [ 
         [0, 0, 0], 
         [0, 0, 1], 
         [0, 0, 2] 
        ] 
       }"; 
    var result = JsonConvert.DeserializeObject<Data>(data); 
} 

[TestMethod] 
public void TestDeserializationMultipleArrays() 
{ 
    // metaGrids is now an array of an array of arrays. 
    var data = @"{ 
        ""metaGrids"": [ 
         [ 
          [0, 0, 0], 
          [0, 0, 1], 
          [0, 0, 2] 
         ], 
         [ 
          [0, 0, 0], 
          [0, 0, 1], 
          [0, 0, 2] 
         ] 
        ] 
       }"; 
    var result = JsonConvert.DeserializeObject<Data>(data); 
} 

Mon objet ressemble à ceci:

public class Data 
{ 
    [JsonConverter(typeof(MetagridsDataConverter))] 
    public int[][][] metaGrids; 
} 

Je suis en train d'utiliser une classe de conversion de données pour faire il fonctionne dans les deux situations, mais cela ne parvient pas pour moi:

public class MetagridsDataConverter : JsonConverter 
{ 
    public override bool CanConvert(Type objectType) 
    { 
     return true; 
    } 

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) 
    { 
     return null; 
    } 

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) 
    { 

    } 
} 

Comment puis-je coder mon convertisseur pour qu'il fonctionne dans les deux situati ons? Dans ma logique ci-dessus, je continue à obtenir cette erreur (même si je suis juste essayer de baseline un cas où je peux obtenir le convertisseur pour déclencher correctement):

Newtonsoft.Json.JsonSerializationException: jeton inattendu lors objet désérialisation : StartArray. Chemin 'metaGrids [0]', ligne 3, la position 33.

+0

Qu'est-ce que vous essayez est d'avoir une ou l'autre liste des listes ou une liste de listes de listes, non? https://stackoverflow.com/a/18997172/7034621 – orhtej2

Répondre

1

Basé sur idée this answer je suis venu avec les éléments suivants:

public class Data 
{ 
    [JsonConverter(typeof(SingleOrArrayConverter))] 
    public int[][][] metaGrids; 
} 

class SingleOrArrayConverter : JsonConverter 
{ 
    public override bool CanConvert(Type objectType) 
    { 
     return (objectType == typeof(List<List<List<int>>>)); 
    } 

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) 
    { 
     JToken token = JToken.Load(reader); 
     if (token.Type == JTokenType.Array) 
     { 

      switch (Dimensions(token)) 
      { 
       case 3: 
        return token.ToObject<int[][][]>(); 
       case 2: 
        return new int[][][] { token.ToObject<int[][]>() }; 
      } 
     } 
     throw new InvalidOperationException("Data is not in a standard supported format."); 
    } 

    private static int Dimensions(JToken token) 
    { 
     if (token.Type != JTokenType.Array) 
      return 0; 
     return 1 + Dimensions(token.First); 
    } 

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) 
    { 
     throw new NotImplementedException(); 
    } 
} 
+0

Cela aura toujours pour résultat que l'instance d'objet aura un type de 'Int32 [] [] []' pour la propriété 'MetaGrids' même si les données sont de type' Int32 [] [] ' –

+0

@AaronRoberts Bien sûr, il doit correspondre au type de l'entité en cours de désérialisation. – orhtej2