Цель:
XML сериализует объект, который содержит список объектов этого и его производных типов. Результирующий XML не должен использовать атрибут xsi: type для описания типа, чтобы имена сериализованных элементов XML были назначенным именем, специфичным для производного типа, а не всегда именем базового класса, что является поведением по умолчанию.
Попытка:
После изучения IXmlSerializable и IXmlSerializable с помощью жутких методов XmlSchemaProvider и отражения voodoo для возврата специализированных схем и XmlQualifiedName в течение нескольких дней я обнаружил, что могу использовать простой атрибут [XmlElement] для достижения цели ... почти.
Проблема:
Переопределенные свойства появляются дважды при сериализации. Исключение гласит: «Элемент XML 'overriddenProperty' из пространства имен '' уже присутствует в текущей области. Используйте атрибуты XML, чтобы указать другое имя XML или пространство имен для элемента". Я попытался использовать * указанное свойство (см. Код), но оно не сработало.
Пример кода:
Class Declaration
using System;
using System.Collections.Generic;
using System.Xml.Serialization;
[XmlInclude(typeof(DerivedClass))]
public class BaseClass
{
public BaseClass() { }
[XmlAttribute("virt")]
public virtual string Virtual
{
get;
set;
}
[XmlIgnore]
public bool VirtualSpecified
{
get { return (this is BaseClass); }
set { }
}
[XmlElement(ElementName = "B", Type = typeof(BaseClass), IsNullable = false)]
[XmlElement(ElementName = "D", Type = typeof(DerivedClass), IsNullable = false)]
public List<BaseClass> Children
{
get;
set;
}
}
public class DerivedClass : BaseClass
{
public DerivedClass() { }
[XmlAttribute("virt")]
public override string Virtual
{
get { return "always return spackle"; }
set { }
}
}
Driver:
BaseClass baseClass = new BaseClass() {
Children = new List<BaseClass>()
};
BaseClass baseClass2 = new BaseClass(){};
DerivedClass derivedClass1 = new DerivedClass() {
Children = new List<BaseClass>()
};
DerivedClass derivedClass2 = new DerivedClass()
{
Children = new List<BaseClass>()
};
baseClass.Children.Add(derivedClass1);
baseClass.Children.Add(derivedClass2);
derivedClass1.Children.Add(baseClass2);
Я боролся с этим в течение нескольких недель и не могу найти ответ нигде.