2009-08-11 4 views
9

次のクラスのバイナリシリアル化を使用して格納されたデータがあります。変更された型の古いデータをどのように非直列化するのですか?

[Serializable] 
public abstract class BaseBusinessObject 
{ 
    private NameValueCollection _fieldErrors = new NameValueCollection(); 

    protected virtual NameValueCollection FieldErrors 
    { 
     get { return _fieldErrors; } 
     set { _fieldErrors = value; } 
    } 

    ... 
} 

ある時点で、クラスが次のように変更されました:

これは古いデータを直列化解除する問題の原因です。

私の最初の考えはISerializableを実装することでしたが、このクラスには数多くのプロパティと継承クラスがあります。

デシリアライズ時に現在の構造と一致するように古いデータを変更するか、古いデータをアップグレードするクリーンな方法が必要です。

答えて

4

新しい名前_ fieldErrorsを別の名前、たとえば_fieldErrors2に追加して[Optional]にします。次に[OnDeserialized]_fieldErrorsから_fieldErrors2(存在する場合)のデータをコピーし、_fieldErrorsをクリアする方法を実装します。

+0

これは私のニーズに最も現実的なアプローチを提供しましたが、別のルートを終了しました。 – ramnik

3

データが内部でのみ使用されている場合は、古い「NameValueCollection」を使用してバイナリデータを非直列化し、それをDictionaryにマップして再直列化する単純なスローアウェイコードを書きます。すべてのデータを処理するのに数日かかる場合でも、古いデータをサポートするために新しいコードにパッチを実装する価値はありません。

内部的に使用されるだけでなく、輸入業者は最も簡単な方法のようです。

2

OlivierDの良いアドバイスに加えて、私は両方のクラスを定義することをお勧めしますが、最初は現在のバージョンとして逆シリアル化しようとします。キャッチブロックで、古いバージョンとしてデシリアライズし、現在のバージョンにアップグレードして元に戻します。レガシーバージョンのインスタンスが存在しない場合は、コードを削除できます。

0

いくつかのオプションを調査した後、私は次のような結論を作った:

理想的には、私は元NameValueCollectionから値にアクセスし、手動Dictionary<string, string>に変換することができるだろう。これを行う唯一の方法はISerializableを実装することですが、これは2つの主要な問題を提起しました:レガシーデータの命名とすべての継承クラス(何百もある)のシリアライゼーションロジックの組み込み。

これは効果的に、私をバインドしてくれました。幸いなことに、このフィールドは実際にフォーム検証エラーの要約としてのみ使用され、最初にシリアル化されるべきではないと判断できるため、シリアル化から除外しました。

関連する問題