是否可以使用Json.NET反序列化内联数组?

时间:2019-06-01 17:43:04

标签: json.net

让我尝试通过从复杂对象和大型JSON文本中提取和抽象相关信息来简化我的问题。

Class Foo()
{
  string Name;
  Version[] versions;
}

JsonText(从XML转换)可以是这样的:

  "Foo": {
    "Name": "test",
    "versions": {
        "Major": "1",
        "Minor": "1"
    },
    "versions": {
        "Major": "2",
        "Minor": "1"
    },
    "versions": {
        "Major": "3",
        "Minor": "1"
    }
    }

或以下内容:

  "Foo": {
    "Name": "test",
    "versions": {
        "Major": "1",
        "Minor": "1"
    }
    }

JsonConvert.DeserializeObject(JsonText)结果为:

Cannot deserialize the current JSON object (e.g. {"name":"value"}) into type 'Version[]' because the type requires a JSON array (e.g. [1,2,3]) to deserialize correctly.

是否可以进行反序列化?

1 个答案:

答案 0 :(得分:1)

根据评论进行了更新

您的Json无效。 Json需要用“ [”“]”括起来。例如,

[ "Ford", "BMW", "Fiat" ]

如果允许您修改Json,则可以按以下方式修改Json

{
"Foo": 
{
    "Name": "test",
    "versions": [
    {
        "Major": "1",
        "Minor": "1"
    },
    {
        "Major": "2",
        "Minor": "1"
    },
    {
        "Major": "3",
        "Minor": "1"
    }]
}
}

根据您的评论,如果只有一个元素,则希望避免使用Json数组语法。在其他情况下,您想坚持使用数组语法。在这种情况下,您可以编写一个Custom Json Converter。

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

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        JToken token = JToken.Load(reader);
        if (token.Type == JTokenType.Array)
        {
            return token.ToObject<List<T>>().ToArray();
        }
        return new List<T> { token.ToObject<T>() }.ToArray();
    }

    public override bool CanWrite
    {
        get { return false; }
    }

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

您可以使用 JsonConverter 属性装饰您的类,以使用“定制Json转换器”。

class Wrapper
{
    public Foo Foo{get;set;}
}
class Foo
{
  [JsonProperty("Name")]
  public string Name{get;set;}

  [JsonProperty("versions")]
  [JsonConverter(typeof(CustomConverter<Version>))]
  public Version[] versions{get;set;}
}

现在您可以反序列化为

var result =JsonConvert.DeserializeObject<Wrapper>(str);

现在,如果您使用以下Json定义之一,这将起作用。

 {
    'Foo': 
    {
        'Name': 'test',
        'versions': [
        {
            'Major': '1',
            'Minor': '1'
        },
        {
            'Major': '2',
            'Minor': '1'
        },
        {
            'Major': '3',
            'Minor': '1'
        }]
    }
    }

单个版本(无数组语法)

  {
    'Foo': 
    {
        'Name': 'test',
        'versions': 
        {
            'Major': '1',
            'Minor': '1'
        }
    }
    }