0

ISerializable である複雑なオブジェクトがあり、それを XML ドキュメントにシリアル化したい (ソース コードを変更せず、XML シリアル化属性を追加したくないノード)。ISerializable は BinaryFormatter で問題なく動作しますが、XML または Json にシリアル化する標準的な方法はありません。Json.NET ライブラリは、ISerializable オブジェクトを json にシリアライズすることをサポートしていますが、その実装には非常に小さな問題があり、Json.net がそれを検出するには、クラスのシリアライズ可能なコンストラクタを public にする必要があります (この問題を参照) 。これにより、私の場合はJson.netが使用できなくなります。

ISerializable オブジェクトを xml、Json、またはその他のプレーン テキスト形式との間でシリアライズ/デシリアライズする他の方法はありますか?

4

2 に答える 2

1

実際、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インターフェイスを介してシリアル化されるはずです。

最高のパフォーマンスを得るために、コントラクト リゾルバーをキャッシュすることをお勧めします。

于 2016-07-04T22:35:44.263 に答える