Question

J'ai des données qui ont été stockées en utilisant sérialisation binaire pour la classe suivante:

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

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

    ...
}

À un certain moment, la classe a été changé à ceci:

[Serializable]
public abstract class BaseBusinessObject
{
    private Dictionary<string, string> _fieldErrors = new Dictionary<string, string>();

    protected virtual Dictionary<string, string> FieldErrors
    {
        get { return _fieldErrors; }
        set { _fieldErrors = value; }
    }

    ...
}

est à l'origine des problèmes désérialisation anciennes données.

Ma première pensée était de mettre en œuvre ISerializable, mais cette classe possède de nombreuses propriétés ainsi que des centaines de héritant des classes que j'aurais à mettre en œuvre ce aussi bien.

Je voudrais soit modifier les anciennes données pour correspondre à la structure actuelle lors de la désérialisation ou ont une manière propre de mettre à niveau les anciennes données.

Était-ce utile?

La solution

Ajoutez le nouveau _fieldErrors sous un autre nom, dire _fieldErrors2 et faire [Optional] . Ensuite, mettre en œuvre un [OnDeserialized] Méthode qui copie les les données de _fieldErrors à _fieldErrors2 (le cas échéant), et efface _fieldErrors.

Autres conseils

Si les données ne sont utilisées en interne, ma première pensée serait d'écrire un code jetable simple à désérialiser vos données binaires en utilisant l'ancienne « NameValueCollection », la carte à un Dictionnary et re-sérialiser. Même si ça va prendre quelques jours pour traiter toutes les données, il ne semble pas la peine de mettre en œuvre un patch sur votre nouveau code pour soutenir les anciennes données.

Même si elle est non seulement utilisé en interne, un importateur semble que le moyen le plus simple d'aller.

Ajout de bons conseils de OlivierD, je vous suggère de définir les deux classes, mais essayez d'abord désérialiser que la version actuelle. Dans votre bloc catch, désérialiser comme la version héritée, puis mettez à niveau à l'actuel et l'enregistrer en arrière. En l'absence de cas de la version héritée existent, vous pouvez supprimer le code.

Après avoir enquêté sur quelques options, je fait les conclusions suivantes:

Je l'idéal de pouvoir accéder à la valeur de la NameValueCollection et de le convertir manuellement à Dictionary<string, string>. La seule façon de le faire serait de mettre en œuvre ISerializable, mais cela pose deux problèmes majeurs: correspondant à la désignation des données existantes et l'inclusion de la logique de sérialisation pour toutes les classes héritant (dont il existe des centaines).

En fait, cela m'a mis dans une impasse. Heureusement, je suis en mesure de déterminer que ce champ est vraiment utilisé comme un résumé de la forme des erreurs de validation et ne doit pas être obtenir sérialisé en premier lieu, donc je l'ai exclue de sérialisation.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top