4

次のメソッドを使用して、.NETオブジェクトをシリアル化および逆シリアル化します。

public static string SerializeToBase64(object data)
{
    var stream = new MemoryStream();
    var formatter = new BinaryFormatter();
    formatter.Serialize(stream, data);
    stream.Position = 0;
    return Convert.ToBase64String(stream.ToArray());
}

public static object DeserializeFromBase64(string data)
{
    var stream = new MemoryStream(Convert.FromBase64String(data));
    stream.Position = 0;
    var formatter = new BinaryFormatter();
    return formatter.Deserialize(stream);
}

これらのメソッドは、[Serializable]属性でマークされた単純なクラスを操作するときに正常に機能するようです。

ただし、このコードを使用して、ORMフレームワークによって作成されたエンティティクラス(Serializableとしても作成)をシリアル化する必要があります。これにより、各エンティティクラスは、ソースコードがない基本クラスから派生します。

エンティティクラスのインスタンスを操作する場合、例外なしでシリアル化を完了しますが、formatter.Deserialize()を実行すると、逆シリアル化は常にnull参照例外をスローします。

私はシリアル化のプロセスにあまり精通していませんが、この問題はターゲットオブジェクトの状態の異常が原因であると考えられます。シリアル化の前にオブジェクトが満たさなければならない標準の基準セットはありますか?

他のデバッグの提案をいただければ幸いです。

ありがとう、ティム

アップデート:

さらに実験を重ねた結果、問題の原因を発見したと思います。この投稿で説明されているように、ターゲットオブジェクトには、シリアル化可能としてマークされていない別のクラスによって処理されるイベントがあります。

興味深いのは、イベントハンドラーが接続されていても、シリアル化が正しく機能することです。逆シリアル化が失敗します。

ただし、イベントハンドラーを一時的に削除してテストしたところ、シリアル化と逆シリアル化の両方が正しく機能するため、これが問題であると思います。ただし、イベントが宣言されているコードにアクセスできないため、上記のソリューションを実装する方法をすぐに理解することはできません。シリアル化プロセスを変更して、イベントハンドラーを削除してから復元する必要がある場合があります。

4

2 に答える 2

1

どの ORM フレームワークですか? ORM で生成された型は、常に「POCO」であるとは限らないため、と一緒に使用すると特に不快になる傾向があることに注意してください。ORM に関連するフィールドが含まれていることが多いため、スタンドアロンで作成すると問題が発生します。要するに、この場合にうまくいかなくてもBinaryFormatter、私はそれほど驚くことではありません。

DataContractSerializerXmlSerializer、protobuf-netなどの使用を検討することをお勧めしますNetDataContractSerializer。これらはすべて同様の機能を果たしますが、(フィールドではなく) パブリック プロパティで動作するため、より効果的である傾向があります。 DTO として使用するためのこれらのアプローチ。

于 2010-01-28T16:34:32.683 に答える
0

ORM 基底クラス アセンブリで Reflector を使用できますか? 例外の原因となっているカスタム デシリアライゼーション コードがある可能性があります (つまり、ISerializableインターフェイスを実装しています)。それが事実であり、それが何をしているのかがわかれば、サブクラスのインスタンスに十分な状態を設定して、それが起こらないようにすることができるかもしれません。一方、バグがある場合は、少し運が悪いです。

于 2010-01-28T16:35:12.117 に答える