0

次のような構造の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プロパティに使用する必要があるタイプを理解できません-配列または任意のオブジェクトタイプは不適切です。私が今考えているのは、ブレースを( simple の正規表現でString.Replace)置き換えることだけですが、これを逆シリアル化するためのより適切な方法があるはずです。

4

2 に答える 2

4

必要なことは、カスタム コンバーターを作成し、継承を使用することです。

まず、2 つのサブクラスがあるように変更しました。

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

    }
}

おそらく、JArray を実際の配列型に対して変更したいと思うでしょうJsonTestResultArray

于 2014-08-08T05:45:53.717 に答える