使用不同的对象类型反序列化JSON [英] Deserializing JSON with different object types

查看:115
本文介绍了使用不同的对象类型反序列化JSON的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个具有以下结构的json:

I have a json with structure like this:

{
   "result":
   [
      {"a":{"b":1,"c":2}},
      {"a":{"b":1,"c":2}},
      {"a":{"b":1,"c":2}},
      {"a":[]}
   ]
}

所以我创建了类结构以将其解析为C#对象:

So I created class structure to parse this into C# objects:

public class JsonTest
{
   public JsonTestResult[] result;
}

public class JsonTestResult
{
   public JsonTestResultValue a;
}

public class JsonTestResultValue
{
   public int b;
   public int c;
}

当尝试通过LitJson解析此错误时,出现错误:

when trying to parse this via LitJson I get an error:

类型JsonTestResultValue不能用作数组

Type JsonTestResultValue can't act as an array

问题出在json的这一部分:{"a":[]},必须存在{}而不是[],因为它实际上是对象,而不是数组.

the problem is in this part of the json: {"a":[]}, there must be {} instead of [], because it's really an object, not an array.

现在我被困在这里,无法理解我必须为此json属性使用哪种类型-数组或任何对象类型都不适合.我现在想到的只是替换括号(使用简单的String.Replace的Regex),但是我敢肯定,必须有更充分的方法来反序列化.

Now I'm stuck here and can't understand which type that I must use for this json property - array or any object type is unsuitable. All that I have on my mind now is to replace braces (with Regex of simple String.Replace), but I'm sure, there must be more adequate way to deserialize this.

推荐答案

您需要做的是创建一个自定义转换器并使用继承.

What you need to do is to create a custom converter and use inheritance.

首先,我进行了更改,以便有两个子类:

To start with I've changed so that there are two subclasses:

public class JsonTestObject
{

}

public class JsonTestResultValue : JsonTestObject
{
    public int b;
    public int c;
}

public class JsonTestResultArray : JsonTestObject
{
    public JArray Array { get; set; }

    public JsonTestResultArray(JArray array)
    {
        Array = array;
    }
}

主要结构中使用了哪些

public class JsonTest
{
    public JsonTestResult[] result;
}

public class JsonTestResult
{
    public JsonTestObject a;
}

然后,我们需要能够确定要使用哪些子类.为此,我们可以检查开始标记是用于对象还是用于数组.这是在JsonConverter:

We then need to be able to identify which of the subclasses to use. To do that we can check if the start token is for an object or for an array. that is done inside a JsonConverter:

public class JsonTestConverter : JsonConverter
{
    public override bool CanConvert(Type objectType)
    {
        return typeof(JsonTestObject).IsAssignableFrom(objectType);
    }

    public override object ReadJson(JsonReader reader,
        Type objectType, object existingValue, JsonSerializer serializer)
    {
        //Is it an array?
        var token = reader.TokenType;
        if (token == JsonToken.StartArray)
        {
            var array = JArray.Load(reader);
            return new JsonTestResultArray(array);
        }

        var item = JObject.Load(reader);
        return item.ToObject<JsonTestResultValue>();
    }

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

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

最后,在反序列化时必须指定转换器:

Finally you have to specify the converter when deserializing:

class Program
{
    static void Main(string[] args)
    {
        var str = @"{
        ""result"":
        [
           {""a"":{""b"":1,""c"":2}},
           {""a"":{""b"":1,""c"":2}},
           {""a"":{""b"":1,""c"":2}},
           {""a"":[]}
        ]
    }";
        var deserializedObject = JsonConvert.DeserializeObject<JsonTest>(str, new JsonTestConverter());

    }
}

您可能想针对JsonTestResultArray中的实际数组类型更改JArray.

You probably want to change the JArray against your real array type in the JsonTestResultArray.

这篇关于使用不同的对象类型反序列化JSON的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆