Pregunta

Tengo datos que han sido almacenados utilizando la serialización binaria para la siguiente clase:

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

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

    ...
}

En algún momento, la clase fue cambiado a esto:

[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; }
    }

    ...
}

Esto está causando problemas deserializar datos antiguos.

Mi primer pensamiento fue para implementar ISerializable, pero esta clase tiene numerosas propiedades, así como cientos de heredar clases que tendría que implementar esto para también.

Me gustaría cambiar cualquiera de los datos antiguos para que coincida con la estructura actual durante la deserialización o tiene una forma limpia de la actualización de los datos antiguos.

¿Fue útil?

Solución

Añadir el nuevo _fieldErrors con un nombre diferente, por ejemplo _fieldErrors2, y que sea [Optional] . A continuación, poner en práctica un href="http://msdn.microsoft.com/en-us/library/system.runtime.serialization.ondeserializedattribute.aspx" rel="nofollow noreferrer"> [OnDeserialized] Método que copia las datos de _fieldErrors a _fieldErrors2 (si está presente), y borra _fieldErrors.

Otros consejos

Si los datos sólo se utiliza internamente, lo primero que pensé sería escribir algún código simple de usar y tirar para de-serializar los datos binarios usando el viejo "NameValueCollection", asignarla a un Dictionnary y volver a serializar. Incluso si se va a tomar unos días para procesar todos los datos, no parece que vale la pena para implementar un parche en su nuevo código para apoyar los datos antiguos.

Aunque no sólo se usa internamente, un importador parece la forma más sencilla de ir.

La adición de un buen consejo de OlivierD, sugeriría que defina ambas clases pero inicialmente intenta deserializar que la versión actual. En el bloque catch, deserializar como la versión legado, a continuación, actualizar a la actual y guardarlo de nuevo. Cuando no existen instancias de la versión legado, puede eliminar el código.

Después de investigar algunas opciones, que formuló las siguientes conclusiones:

Lo ideal sería capaz de acceder al valor de la NameValueCollection original y convertirlo manualmente a Dictionary<string, string>. La única manera de hacer esto sería la implementación de ISerializable, pero esto plantea dos cuestiones principales: a juego hasta el nombramiento de los datos existentes y la inclusión de la lógica de serialización para todas las clases que heredan (de los cuales hay cientos).

Efectivamente, esto me puso en un aprieto. Afortunadamente, pude determinar que este campo es realmente sólo se utiliza como un resumen de los errores de validación de formularios y no se debe conseguir serializado en primer lugar, por lo tanto, he excluido de serialización.

scroll top