このプロジェクトは、Asp.Net WebAPIWebサービスです。
Jsonとの間でシリアル化できるようにする必要がある型階層があるため、このSOからコードを取得しました:JSON.NETでカスタムJsonConverterを実装して、基本クラスオブジェクトのリストを逆シリアル化するにはどうすればよいですか?、そしてコンバーターを私の階層の基本クラスに適用しました。このようなもの(無関係を隠すためにここに擬似コードがあります):
[JsonConverter(typeof(TheConverter))]
public class BaseType
{
// note the base of this type here is from the linked SO above
private class TheConverter : JsonCreationConverter<BaseType>
{
protected override BaseType Create(Type objectType, JObject jObject)
{
Type actualType = GetTypeFromjObject(jObject); /*method elided*/
return (BaseType)Activator.CreateInstance(actualType);
}
}
}
public class RootType
{
public BaseType BaseTypeMember { get; set; }
}
public class DerivedType : BaseType
{
}
したがって、のインスタンスと等しいRootType
インスタンスを逆シリアル化すると、そのタイプのインスタンスに逆シリアル化されます。BaseTypeMember
DerivedType
ちなみに、これらのJSONオブジェクトには、'$type'
仮想型名(完全な.Net型名ではない)を含むフィールドが含まれているため、シリアル化および逆シリアル化できる型を正確に制御しながら、JSONで型を同時にサポートできます。
これで、リクエストから値を逆シリアル化するのに非常にうまく機能します。しかし、シリアル化に問題があります。リンクされたSO、そして実際にトップアンサーからリンクされているJson.Netの議論を見ると、私が使用しているベースコードは完全に逆シリアル化を対象としていることがわかります。シリアライザーの手動作成を示すその使用例を示します。これJsonConverter
によってテーブルにもたらされた実装は、JsonCreationConverter<T>
単に。をスローしNotImplementedException
ます。
ここで、Web APIがリクエストに単一のフォーマッターを使用する方法のため、WriteObject
メソッドに「標準」のシリアル化を実装する必要があります。
この時点で、プロジェクトのこの部分に着手する前に、すべてがエラーなしで適切にシリアル化されたことを強調する必要があります。
だから私はこれをしました:
public override void WriteJson(JsonWriter writer,
object value,
JsonSerializer serializer)
{
serializer.Serialize(writer, value);
}
しかし、オブジェクトの1つがシリアル化されると、 JsonSerializationException
:が表示されます。Self referencing loop detected with type 'DerivedType'
繰り返しますが、コンバーター属性を削除すると(カスタム作成を無効にすると)、正常に機能します...
これは、私のシリアル化コードが実際に同じオブジェクトでコンバーターを再度トリガーしていることを意味していると感じています。これにより、シリアライザーが再び呼び出されます。確認済み-私の答えを参照してください
では、機能するのと同じ「標準」シリアル化を実行するために、どのコードを記述する必要がありますか?WriteObject