Исключения нулевой ссылки во время десериализации Base64 (C #) - PullRequest
4 голосов
/ 28 января 2010

Я использую следующие методы для сериализации и десериализации объектов .NET:

public static string SerializeToBase64(object data)
{
    var stream = new MemoryStream();
    var formatter = new BinaryFormatter();
    formatter.Serialize(stream, data);
    stream.Position = 0;
    return Convert.ToBase64String(stream.ToArray());
}

public static object DeserializeFromBase64(string data)
{
    var stream = new MemoryStream(Convert.FromBase64String(data));
    stream.Position = 0;
    var formatter = new BinaryFormatter();
    return formatter.Deserialize(stream);
}

Эти методы работают нормально при работе с простыми классами, помеченными атрибутом [Serializable].

Но мне нужно использовать этот код для сериализации классов сущностей (также обозначаемых как Serializable), созданных средой ORM, в результате чего каждый класс сущностей является производным от базового класса, для которого у меня нет исходного кода.

При работе с экземплярами класса сущности он завершает сериализацию без исключений, но десериализация всегда выдает исключение нулевой ссылки при исключении formatter.Deserialize ().

Я не очень знаком с процессом сериализации, но я предполагаю, что эта проблема должна быть вызвана чем-то аномальным в состоянии целевого объекта. Существует ли стандартный набор критериев, которым объект должен соответствовать перед сериализацией?

Будем благодарны за любые другие предложения по отладке.

Спасибо, Тим

UPDATE:

После дальнейших экспериментов, я думаю, я обнаружил причину проблемы. Целевой объект имеет события, которые обрабатываются другим классом, который не помечен как сериализуемый, как описано в этом посте .

Что интересно, так это то, что serialaztion работает корректно, даже с подключенными обработчиками событий - это десериализация, которая терпит неудачу.

Но я проверил, временно удалив обработчики событий, и сериализация и десериализация работают правильно, поэтому я предполагаю, что это проблема. Однако, поскольку у меня нет доступа к коду, в котором объявлены события, я не могу сразу увидеть, как реализовать решение, описанное выше. Возможно, мне придется изменить процесс сериализации, чтобы удалить, а затем восстановить обработчики событий.

Ответы [ 2 ]

1 голос
/ 28 января 2010

Какая платформа ORM это? Обратите внимание, что сгенерированные ORM типы имеют тенденцию быть особенно неприятными при использовании с BinaryFormatter, поскольку они не всегда "POCO": у них часто есть поля, которые относятся к ORM - поэтому создание их автономно имеет проблемы , Короче говоря, я не сильно удивлен, что это не работает в этом случае.

Возможно, вы захотите использовать что-то вроде DataContractSerializer, XmlSerializer, protobuf-net или, возможно, NetDataContractSerializer - все они выполняют аналогичную работу, но поскольку они работают с общими свойствами (а не с полями), они имеют тенденцию быть более эффективными - и действительно, многие имеют встроенную поддержку этих подходов для использования в качестве DTO.

0 голосов
/ 28 января 2010

Можно ли использовать Reflector в сборке базового класса ORM?Там может быть некоторый пользовательский код десериализации, который вызывает исключение (то есть он реализует интерфейс ISerializable).Если вы можете выяснить, в чем дело и что он делает, вы можете установить достаточно состояния в экземпляре подкласса, чтобы это не происходило.С другой стороны, если в нем есть ошибка, то вам немного не повезло.

...