XmlSerializer, XmlArray с динамическим контентом ... как? - PullRequest
2 голосов
/ 05 апреля 2011

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

У меня есть иерархия классов, которые должны быть сериализуемыми и десериализуемыми из «Конверта». Он имеет элемент массива с именем «Items», который может содержать подклассы абстрактного «Item».

[XmlArray("Items")]
public Item [] Items { get; set; }

Теперь мне нужно добавить XmlArrayItem, но число не является «фиксированным». До сих пор мы использовали отражение, чтобы найти все подклассы с KnownTypeProvider, чтобы легко расширять сборку новыми подтипами. Я действительно не хочу жестко закодировать все элементы здесь.

Класс определяется соответственно:

[XmlRoot]
[KnownType("GetKnownTypes")]
public class Envelope {

но это не помогает.

Изменение элементов на:

[XmlArray("Items")]
[XmlArrayItem(typeof(Item))]
public Item [] Items { get; set; }

Результат:

{"Тип xxx.Adjustment не ожидал Используйте XmlInclude или атрибут SoapInclude для указания типы, которые не известны статически. "}

при попытке сериализации.

Кто-нибудь знает, как я могу использовать XmlInclude, чтобы указать на поставщика известного типа?

Ответы [ 2 ]

2 голосов
/ 18 апреля 2011

Атрибут KnownTypesAttribute не работает для XmlSerializer.Он используется только DataContractSerializer.Я вполне уверен, что вы можете обменять сериализатор в WCF, потому что я сделал это для DataContractSerializer.Но если это не вариант, вы должны реализовать IXmlSerializable самостоятельно и обработать поиск типов там.

Прежде чем дисквалифицировать это решение: вам просто нужно реализовать IXmlSerializable только для специального класса, который заменяет Item [].Все остальное может обрабатываться сериализатором по умолчанию.

1 голос
/ 11 апреля 2011

Согласно: http://social.msdn.microsoft.com/Forums/en-US/asmxandxml/thread/83181d16-a048-44e5-b675-a0e8ef82f5b7/

вы можете использовать другой конструктор XmlSerializer :

new XmlSerializer(typeof(Base), new Type[] { typeof(Derived1), ..});

Вместо перечисления всех производных классов в базовом определении, например:

[System.Xml.Serialization.XmlInclude(typeof(Derived1))]
[System.Xml.Serialization.XmlInclude(typeof(Derived2))]
[System.Xml.Serialization.XmlInclude(typeof(DerivedN))]

Я думаю, что вы сможете использовать KnownTypeProvider для заполнения массива в конструкторе XmlSerializer .

...