【问题标题】:Deserialize this object with Json.NET使用 Json.NET 反序列化此对象
【发布时间】:2018-02-22 12:03:23
【问题描述】:

我想让两个测试方法通过:

[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: Unexpected token when 反序列化对象:StartArray。路径 'metaGrids[0]',第 3 行, 第 33 位。

【问题讨论】:

标签: c# arrays json multidimensional-array json.net


【解决方案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();
    }
}

【讨论】:

  • 这仍然会导致对象实例的 Int32[][][] 类型为 MetaGrids 属性,即使数据类型为 Int32[][]
  • @AaronRoberts 当然会,它必须匹配被反序列化的实体的类型。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-01-01
相关资源
最近更新 更多