Как обойти проблему XmlSerialization с псевдонимами имен типов (в .NET)? - PullRequest
2 голосов
/ 15 сентября 2009

У меня есть коллекция объектов, и для каждого объекта у меня есть тип FullName и либо его значение (в виде строки), либо поддерево деталей внутренних объектов (снова введите FullName и значение или поддерево). Для каждого корневого объекта мне нужно создать фрагмент XML, который будет десериализуемым в xml.

Проблема с XmlSerializer заключается в том, что то есть следующий объект

int age = 33;

будет сериализовано до

<int>33</int>

Сначала кажется, что все в порядке, но при работе с отражением вы будете использовать System.Int32 в качестве имени типа, а int - псевдоним, а этот

<System.Int32>33</System.Int32>

не десериализуется.

Теперь дополнительная сложность связана с тем, что мне нужно обрабатывать любой возможный тип данных. Поэтому решения, использующие System.Activator.CreateInstance (..) и приведение типов, не сработают, если я не пойду по пути генерации и компиляции кода как способа достижения этого (чего я бы предпочел избежать) 1022 *

Примечания: Быстрое исследование с использованием .NET Reflector показало, что XmlSerializer использует внутренний класс TypeScope , посмотрите на его статический конструктор и убедитесь, что он инициализирует внутренний HashTable с отображениями.

Итак, вопрос в том, что является лучшим (и я имею в виду элегантный и солидный) способ обойти этот печальный факт?

Ответы [ 2 ]

1 голос
/ 17 сентября 2009

Я не совсем понимаю, откуда возникла ваша проблема. XmlSerializer будет использовать тот же синтаксис / отображение для сериализации, что и для десериализации, поэтому при его использовании для сериализации и десериализации не возникает конфликтов. Возможно, используемые теги типа являются чем-то вроде стандарта xml, но не уверены в этом. Я предполагаю, что проблема заключается в вашем использовании отражения. Вы инстанцируете свой импортировать / десериализовать объекты, вызвав Activator.CreateInstance? Вместо этого я бы порекомендовал следующее, если у вас есть какой-то тип Foo, который будет создан из xml в xmlReader:

Foo DeserializedObject = (Foo)Serializer(typeof(Foo)).Deserialize(xmlReader);

В качестве альтернативы, если вы не хотите полностью переключаться на XmlSerializer, вы можете выполнить некоторую предварительную обработку вашего ввода. Тогда стандартным способом будет создание некоторого XSLT, в котором вы преобразуете все эти элементы типа в их псевдонимы или наоборот. затем перед обработкой XML вы применяете свое преобразование с помощью System.Xml.Xsl.XslCompiledTransform и используете ваши (или отражающие) отображения для каждого типа.

0 голосов
/ 15 сентября 2009

Почему бы вам не сериализовать весь тип поля как атрибут?

Вместо

<age>
  <int>33</int>
</age>

вы могли бы сделать

<age type="System.Int32">
  33
</age>
...