Проблема сериализации: разные пространства имен (.NET) - PullRequest
0 голосов
/ 16 апреля 2010

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

Для обработки старых версий объектов я написал конвертер, который десериализует объект в мыле и повторно сериализует его в двоичном виде.

Конвертер использует версии классов во время переключения, поэтому я поместил эти классы в другое пространство имен, чтобы избежать конфликтов с текущими версиями.

Вот проблема: пространство имен, по-видимому, сериализовано с классом, поэтому я получаю сообщение об ошибке: Невозможно привести NamespaceA.class к NamespaceB.class (Arrgh!)

Классы абсолютно одинаковые; Единственная проблема - это пространства имен. Как я могу заставить фреймворк игнорировать пространства имен?

Ответы [ 2 ]

2 голосов
/ 16 апреля 2010

Согласно этой публикации в группе новостей, Изменение пространства имен приводит к ошибкам при использовании «BinaryFormatter.Deserialize» для перезагрузки данных объекта, сохраненных в то время, как они определены в другом именном пространстве (sic) , вы должны посмотреть на SerializationBinder класс.

Однако я бы настоятельно рекомендовал вам найти другой способ обработки ваших данных, поскольку двоичный форматер предназначен для использования в качестве кратковременного обработчика транспортной упаковки, а не обработчика хранилища.

Рассматривали ли вы в качестве примера буферы протокола


Редактировать : Хорошо, после прочтения вашего комментария и повторного чтения вашего вопроса, выясняется, что ваш вопрос не имеет никакого отношения к сериализации, двоичному или иному.

Проблема, по-видимому, в том, что вы сериализовали класс типа A и пытаетесь десериализовать его или привести его после десериализации к типу B, другому типу.

Это, конечно, не будет работать сразу после установки и может быть легко воспроизведено без использования сериализации, вы просто делаете это:

public class A { ... } <-- a class with some properties and stuff
public class B { ... } <-- another class, with the same properties and stuff

public void Test()
{
    A a = new A();
    B b = a;           <-- you get the same problem as in your code here
}

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

Вы можете реализовать метод типа «клонер», который принимает объект типа A, создает новый объект типа B и копирует все свойства и прочее.

Обратите внимание, что XML-сериализация использует тип, который вы ей даете, в качестве корневого типа, что означает, что вы можете сериализовать объект типа A и десериализовать его как объект типа B, при условии, что вы передаете B объекту сериализации только когда вы намерены десериализовать и при условии, что этот тип имеет достаточно метаданных, чтобы выглядеть как объект типа A.

У меня к вам контрольный вопрос, который может дать нам некоторое представление о том, почему вы пытаетесь это сделать: почему вы не можете десериализовать его как исходный тип и оставить его при этом? Почему вы должны разыграть его?

0 голосов
/ 16 апреля 2010

Вы можете найти, что DataContractSerializer и XmlSerializer будут более щадящими. XmlSerializer отлично подходит практически для любого формата XML. DataContract имеет несколько дополнительных ограничений (например, он не очень хорошо работает с атрибутами), но все равно должен отлично работать в вашем сценарии.

...