私の問題は、JSONをインターフェイスタイプオブジェクトを含むタイプに逆シリアル化する必要があるため、そのインターフェイスタイプを変換する方法をJson.NETに指示する必要がありますが、Newtonsoft.Json.Deserializer
直接制御することはできません。デシリアライズは、フレームワークコード、つまりHttpContent.ReadAsAsync<T>によって間接的に処理されます。
JsonSerializer.Converters
コンバータを直接追加することなく、インターフェイスタイプから具象タイプへの変換を指定するにはどうすればよいですか?インターフェイス定義で属性を使用する[JsonConverter]
と、コンバータはインターフェイスの実装(つまり、変換先の具象型)も呼び出されます。
Parent2
次のコードは、同じJSONを最初にクラスに、次にクラスに逆シリアル化しようとするC#コンソールプログラムを示していますParent1
。Json.NETに、を介してIChild1
インターフェイスタイプをChild1
具象タイプに変換するように指示していますJsonConverterAttribute
。に直接Parent2
追加するため、への逆シリアル化は機能しますが、への逆シリアル化は、型に対しても呼び出されるため、スタックオーバーフロー例外が発生します。ChildConverter
serializer.Converters
Parent1
ChildConverter.Deserialize
Child1
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Newtonsoft.Json;
using System.IO;
namespace TestConsole
{
[JsonConverter(typeof(ChildConverter))]
interface IChild1
{
string Name { get; set; }
}
class Child1 : IChild1
{
public string Name { get; set; }
}
class Parent1
{
public IEnumerable<IChild1> Children { get; set; }
}
interface IChild2
{
string Name { get; set; }
}
class Child2 : IChild2
{
public string Name { get; set; }
}
class Parent2
{
public IEnumerable<IChild2> Children { get; set; }
}
class ChildConverter : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return objectType == typeof(IChild1) || objectType == typeof(IChild2);
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
if (objectType == typeof(IChild1))
return serializer.Deserialize<Child1>(reader);
return serializer.Deserialize<Child2>(reader);
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
throw new NotImplementedException();
}
}
class Program
{
static void Main(string[] args)
{
var json = "{'Children': [{'Name': 'Child1'}, {'Name': 'Child2'}]}";
var serializer = new JsonSerializer();
serializer.Converters.Add(new ChildConverter());
var obj = serializer.Deserialize(new StringReader(json), typeof(Parent2));
serializer = new JsonSerializer();
obj = serializer.Deserialize(new StringReader(json), typeof(Parent1));
}
}
}