実際、Json.NET は型の非パブリック ストリーミング シリアル化コンストラクターをサポートしていISerializable
ます。確認のために、 のソース コードを参照してくださいDefaultContractResolver.CreateISerializableContract()
。
あなたの実際の問題は、問題のISerializable
型がcollectionでもあることです。Json.NET は、JsonISerializableContract
次のように、そのような型の代わりに配列コントラクトを使用しているようです DefaultContractResolver.CreateContract()
。
if (typeof(IEnumerable).IsAssignableFrom(t))
{
return CreateArrayContract(objectType);
}
if (CanConvertToString(t))
{
return CreateStringContract(objectType);
}
#if !(DOTNET || PORTABLE40 || PORTABLE)
if (!IgnoreSerializableInterface && typeof(ISerializable).IsAssignableFrom(t))
{
return CreateISerializableContract(objectType);
}
#endif
この問題を回避するには、このロジックを逆にする独自のカスタム コントラクト リゾルバーを作成します。
public class ISerializableCollectionContractResolver : DefaultContractResolver
{
protected override JsonContract CreateContract(Type objectType)
{
var contract = base.CreateContract(objectType);
var underlyingType = Nullable.GetUnderlyingType(objectType) ?? objectType;
if (!IgnoreSerializableInterface
&& typeof(ISerializable).IsAssignableFrom(underlyingType)
&& contract is JsonArrayContract
&& !underlyingType.GetCustomAttributes<JsonContainerAttribute>().Any())
{
contract = CreateISerializableContract(objectType);
}
return contract;
}
}
カスタム コレクションは、ISerializable
インターフェイスを介してシリアル化されるはずです。
最高のパフォーマンスを得るために、コントラクト リゾルバーをキャッシュすることをお勧めします。