使用Json.NET反序列化此对象

时间:2017-09-13 17:07:43

标签: c# arrays json multidimensional-array 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)
    {

    }
}

如何对转换器进行编码,使其在两种情况下都能正常工作?在我的上述逻辑中,我不断收到此错误(即使我只是尝试基准一个可以让转换器正确触发的情况):

  

Newtonsoft.Json.JsonSerializationException:意外的令牌时   反序列化对象:StartArray。 Path&#39; metaGrids [0]&#39;,第3行,   第33位。

1 个答案:

答案 0 :(得分: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();
    }
}