Мой сценарий:
У меня есть объект, который я определил со свойствами, которые украшены тегами XmlElement и которые имеют типы, которые я определил, некоторые из которых набираются как абстрактные, которые устанавливаются в соответствующие производные типы. Я хочу, чтобы сериализовать весь этот объект в XML с помощью XmlSerializer, и все свойства, которые являются абстрактными, должны быть сериализованы как элементы с TypeName, установленными в TypeName производного типа.
Это пример того, как объекты структурированы:
[XmlType(TypeName = "MAINOBJECT")]
public class MainObject
{
[XmlElement(Type = typeof(DerivedClass))]
public BaseClass TheBase { get; set; }
}
[XmlInclude(typeof(DerivedClass))]
public abstract class BaseClass
{
[XmlAttribute("AnAttribute")]
public string AnAttribute { get; set; }
[XmlElement("ANELEMENT")]
public string AnElement { get; set; }
}
[XmlType(TypeName = "DERIVEDCLASS")]
public class DerivedClass : BaseClass
{
[XmlElement("ANOTHERELEMENT")]
public string AnotherElement { get; set; }
}
Обратите внимание, однако, что когда я создаю новый экземпляр MainObject, заполняю его свойства и сериализую его, это выглядит так:
<MAINOBJECT>
<BaseClass AnAttribute="">
<ANELEMENT/>
<ANOTHERELEMENT/>
</BaseClass>
</MAINOBJECT>
Я хочу, чтобы это:
<MAINOBJECT>
<DERIVEDCLASS AnAttribute="">
<ANELEMENT/>
<ANOTHERELEMENT/>
</DERIVEDCLASS>
</MAINOBJECT>
Вы знаете, что я делаю неправильно здесь?
Добавьте имя XmlElement в TheBase
в MainObject
следующим образом:
[XmlType(TypeName = "MAINOBJECT")]
public class MainObject
{
[XmlElement("DERIVEDCLASS", Type = typeof(DerivedClass))]
public BaseClass TheBase { get; set; }
}
Мне кажется, что лучшим решением здесь будет реализация интерфейса IXmlSerializable, чтобы вы могли полностью контролировать, как объекты становятся сериализованными. Конечно, это больше работает, но если у вас есть такие требования, которые несколько отличаются от обычных, то вы также можете столкнуться с дополнительными причудами, где стандартный XmlSerializer не будет работать для вас по дороге.
Здесь есть хороший учебник: как правильно реализовать IXmlSerializable
Кроме того, здесь есть хорошая информация: Правильный способ реализации IXmlSerializable?
Возможно, это не лучшее решение, но:
class Program
{
static void Main(string[] args)
{
XmlAttributes attrs = new XmlAttributes();
XmlElementAttribute attr = new XmlElementAttribute();
attr.ElementName = "DerivedClass";
attr.Type = typeof(DerivedClass);
attrs.XmlElements.Add(attr);
XmlAttributeOverrides attrOverrides = new XmlAttributeOverrides();
attrOverrides.Add(typeof(MainObject), "TheBase", attrs);
XmlSerializer s = new XmlSerializer(typeof(MainObject), attrOverrides);
StringWriter writer = new StringWriter();
MainObject mo = new MainObject { TheBase = new DerivedClass { AnAttribute = "AnAttribute", AnElement = "AnElement", AnotherElement = "AotherElement" } };
s.Serialize(writer, mo);
Console.Write(writer.ToString());
}
}
public BaseClass TheBase
иpublic BaseClass TheBase2
.