Pergunta

Eu tenho dados que foram armazenados usando serialização binária para a seguinte classe:

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

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

    ...
}

Em algum momento, a classe foi alterado para o seguinte:

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

    ...
}

Isso está causando problemas desserializar dados antigos.

Meu primeiro pensamento foi para implementar ISerializable, mas esta classe tem várias propriedades, bem como centenas de herança de classes que eu teria que implementar isso para bem.

Gostaria que quer mudar os dados antigos para coincidir com a estrutura atual durante a desserialização ou ter uma forma limpa de atualizar os dados antigos.

Foi útil?

Solução

Adicione o novo _fieldErrors sob um nome diferente, dizem _fieldErrors2, e torná-lo [Optional] . Em seguida, implementar um href="http://msdn.microsoft.com/en-us/library/system.runtime.serialization.ondeserializedattribute.aspx" rel="nofollow noreferrer"> [OnDeserialized] Método _fieldErrors para _fieldErrors2 (se presente), e limpa _fieldErrors.

Outras dicas

Se os dados só é usado internamente, o meu primeiro pensamento seria escrever algum código descartável simples para de-serialize os dados binários usando o velho "NameValueCollection", mapeá-lo para um Dictionnary e re-serialize-la. Mesmo se ele vai levar alguns dias para processar todos os dados, não parece valer a pena para implementar um patch no seu novo código para suportar os dados antigos.

Mesmo se não for utilizado internamente, um importador parece ser a maneira mais simples para ir.

Adicionando um bom conselho de OlivierD, eu sugiro que você definir ambas as classes, mas, inicialmente, tentar anular a serialização como a versão atual. Em seu bloco catch, desserializá-lo como a versão legado, em seguida, atualizá-lo para o atual e salvá-lo de volta. Quando há instâncias da versão legado existir, você pode remover o código.

Depois de investigar algumas opções, eu fiz as seguintes conclusões:

Idealmente, eu seria capaz de acessar o valor do NameValueCollection original e manualmente convertê-lo para Dictionary<string, string>. A única maneira de fazer isso seria implementar ISerializable, mas isso colocou duas questões principais: combinando-se com a nomeação dos dados legados ea inclusão de lógica de serialização para todas as classes que herdam (dos quais existem centenas).

Efetivamente, isso me colocar em um ligamento. Felizmente, eu era capaz de determinar que este campo é realmente usado apenas como um resumo dos erros de validação de formulário e não deve ser ficar serializado em primeiro lugar, por isso eu ter excluído-lo de serialização.

scroll top