2009-08-11 8 views
9

que tienen datos que han sido almacenados utilizando la serialización binaria para la siguiente clase:¿Cómo deserializo datos viejos para un tipo que ha cambiado?

[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 implementar ISerializable, pero esta clase tiene numerosas propiedades, así como cientos de clases heredadas que tendrían que implementar también.

Me gustaría cambiar los datos anteriores para que coincidan con la estructura actual durante la deserialización o tener una forma limpia de actualizar los datos antiguos.

Respuesta

4

Agregue el nuevo _ fieldErrors con un nombre diferente, digamos _fieldErrors2 y configúrelo como [Optional]. A continuación, implemente un método [OnDeserialized] que copia los datos de _fieldErrors a _fieldErrors2 (si está presente) y borra _fieldErrors.

+0

Esto proporcionó el enfoque más realista para mis necesidades, pero terminé yendo por una ruta diferente. – ramnik

3

Si los datos solo se usan internamente, lo primero que pensé fue escribir un simple código desechable para deserializar los datos binarios utilizando la antigua "NameValueCollection", asignarla a un Dictionnary y volver a serializarla. Incluso si tomará unos días procesar todos los datos, no parece que valga la pena implementar un parche en su nuevo código para respaldar los datos anteriores.

Incluso si no solo se usa internamente, un importador parece ser la forma más sencilla de hacerlo.

2

Agregando a los buenos consejos de OlivierD, sugiero que defina ambas clases, pero inicialmente intente deserializar como la versión actual. En su bloque catch, deserialícelo como la versión heredada, luego actualícelo al actual y guárdelo nuevamente. Cuando no existen instancias de la versión heredada, puede eliminar el código.

0

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

Lo ideal sería capaz de acceder al valor de la original y de forma manual NameValueCollection convertirlo en Dictionary<string, string>. La única forma de hacerlo sería implementar ISerializable, pero esto planteó dos problemas principales: coincidir con el nombre de los datos heredados y la inclusión de la lógica de serialización para todas las clases heredadas (de las cuales hay cientos).

Efectivamente, esto me puso en un aprieto. Afortunadamente, pude determinar que este campo en realidad solo se usa como un resumen de los errores de validación de formularios y que, en primer lugar, no debería ser serializado, por lo tanto, lo he excluido de la serialización.

Cuestiones relacionadas