2017-09-13 136 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