Deserializing JSON with different object types

喜你入骨 提交于 2019-12-08 13:50:24

问题


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":[]}
   ]
}

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;
}

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

Type JsonTestResultValue can't act as an array

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

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.


回答1:


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;
    }
}

Which are used in the main structure:

public class JsonTest
{
    public JsonTestResult[] result;
}

public class JsonTestResult
{
    public JsonTestObject a;
}

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());

    }
}

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




回答2:


first try to parse the JSON into array . then loop through the array and create object inside the loop.

example

   for(int i = 0 ; i>=JsonArray.Length - 1; i++)
   {
      result[i] = JSON.Deserlize(JsonArray[i]);
   }

PS : Not the tested code just to give you an idea.



来源:https://stackoverflow.com/questions/25196425/deserializing-json-with-different-object-types

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!