JSON 逆シリアル化: あいまいな配列とオブジェクトの処理
JSON データを処理すると、構造的な不一致が頻繁に発生します。一部のプロパティは、あるインスタンスでは配列として表され、別のインスタンスではオブジェクトとして表される場合があります。これにより、特にタイプセーフなクラスを使用する場合、逆シリアル化中に問題が発生する可能性があります。
質問:
Facebook から返された次の JSON データについて考えてみましょう:
壁掛けポスト (オブジェクト):
<code class="language-json"> { "description": "", "permalink": "..." }</code>
写真投稿 (配列):
<code class="language-json"> { "media": [ { "href": "...", "src": "..." } ] }</code>
モバイルウォールポスト (オブジェクト):
<code class="language-json"> { "name": null, "caption": null, "media": {} }</code>
壁の支柱を移動する場合、「メディア」プロパティは配列ではなく空のオブジェクトとして表されます。この違いにより、「FacebookMedia」オブジェクトの配列を期待するクラスを使用する場合、逆シリアル化が失敗します。
解決策: カスタム JSON コンバーター
この状況に対処するために、カスタム JSON コンバーターを作成できます。このコンバーターは JSON 構造を検査し、配列またはオブジェクトの存在に応じてリストまたは null を返します。
<code class="language-csharp">public class FacebookMediaJsonConverter : JsonConverter { public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) { if (reader.TokenType == JsonToken.StartArray) return serializer.Deserialize<List<FacebookMedia>>(reader); else return null; } public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) { throw new NotImplementedException(); } public override bool CanConvert(Type objectType) { return objectType == typeof(List<FacebookMedia>); } }</code>
使用法:
コンバータを使用するには、クラス内のプロパティに [JsonConverter]
属性の注釈を付けます:
<code class="language-csharp">[JsonConverter(typeof(FacebookMediaJsonConverter))] public List<FacebookMedia> Media { get; set; }</code>
逆シリアル化は、「メディア」プロパティの配列とオブジェクトを正常に処理できるようになりました。
単一オブジェクトの拡張子:
オブジェクトが 1 つだけでもリストを受け取りたい場合は、コンバータを拡張して 1 つのオブジェクトをリストに変換できます。
<code class="language-csharp">public class SingleValueArrayConverter<T> : JsonConverter { public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) { object result; if (reader.TokenType == JsonToken.StartObject) { T instance = (T)serializer.Deserialize(reader, typeof(T)); result = new List<T> { instance }; } else if (reader.TokenType == JsonToken.StartArray) { result = serializer.Deserialize(reader, objectType); } else { throw new JsonSerializationException("Unexpected token type."); } return result; } // ... 转换器实现的其余部分 ... }</code>
カスタム JSON コンバーターを使用することで、JSON 構造の不一致を処理し、確実に逆シリアル化を成功させることができます。
以上が逆シリアル化中にあいまいな JSON 配列とオブジェクトを処理するにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。