2017-09-13 132 views
0

我想有两种测试方法通过:反序列化这个对象与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); 
} 

我的目标是这样的:

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

我试图用一个数据转换器类,使它在这两种情况下工作,但这个失败对我来说:

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) 
    { 

    } 
} 

我如何我的代码转换器,这样它会在两个工作situati项?在我上面的逻辑我不断收到此错误(尽管我只是想基线在那里我能得到的转换器正确触发的情况下):

Newtonsoft.Json.JsonSerializationException:意外的令牌时 反序列化对象:StartArray。路径“metaGrids [0]”,3号线, 位置33

+0

什么你想是有名单的任一列表或列表清单,对吗? https://stackoverflow.com/a/18997172/7034621 – orhtej2

回答

1

基于在this answer的想法,我想出了以下内容:

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

这仍然会导致对象实例为'MetaGrids'属性使用'Int32 [] [] []'类型',即使数据类型为' Int32 [] []' –

+0

@AaronRoberts当然,它必须匹配被反序列化的实体的类型。 – orhtej2