使用不同的对象类型反序列化JSON

时间:2014-08-08 05:10:54

标签: c# json litjson

我有一个像这样结构的json:

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

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

public class JsonTest
{
   public JsonTestResult[] result;
}

public class JsonTestResult
{
   public JsonTestResultValue a;
}

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

尝试通过LitJson解析此内容时出现错误:

  

类型JsonTestResultValue不能充当数组

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

现在我被困在这里,无法理解我必须使用哪种类型的json属性 - 数组或任何对象类型都不合适。我现在想到的只是替换括号(使用简单String.Replace的正则表达式),但我确信,必须有更好的方法来反序列化。

2 个答案:

答案 0 :(得分:1)

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

首先,我已经改变,以便有两个子类:

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

中完成的
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();
    }
}

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

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。

答案 1 :(得分:0)

首先尝试将JSON解析为数组。然后遍历数组并在循环内创建对象。

示例

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

PS:不是经过测试的代码只是为了给你一个想法。