XML сериализация и наследуемые типы
Я получил ошибку "{" Тип Device1 не ожидался. Используйте атрибут XmlInclude или SoapInclude, чтобы указать типы, которые статически не известны."}"
В настоящее время у меня есть:
public abstract class Device
{
..
}
public class Device1 : Device
{ ... }
[Serializable()]
public class DeviceCollection : CollectionBase
{ ... }
[XmlRoot(ElementName = "Devices")]
public class XMLDevicesContainer
{
private DeviceCollection _deviceElement = new DeviceCollection();
/// <summary>Devices device collection xml element.</summary>
[XmlArrayItem("Device", typeof(Device))]
[XmlArray("Devices")]
public DeviceCollection Devices
{
get
{
return _deviceElement;
}
set
{
_deviceElement = value;
}
}
}
и я делаю:
XMLDevicesContainer devices = new XMLDevicesContainer();
Device device = new Device1();
device.DeviceName = "XXX";
device.Password = "Password";
devices.Devices.Add(device);
Serializer.SaveAs<XMLDevicesContainer>(devices, @"c:\Devices.xml", new Type[] { typeof(Device1) });
Сериализатор делает:
public static void Serialize<T>(T obj, XmlWriter writer, Type[] extraTypes)
{
XmlSerializer xs = new XmlSerializer(typeof(T), extraTypes);
xs.Serialize(writer, obj);
}
Я упал на последнюю строку в методе сериализатора (xs.Serialize) из-за ошибки: "{" Тип Device1 не ожидался. Используйте атрибут XmlInclude или SoapInclude, чтобы указать типы, которые статически не известны."}"
Я пытался написать XmlInclude для класса Device. не помогло. Если я изменю линию
[XmlArrayItem("Device", typeof(Device))]
быть
[XmlArrayItem("Device", typeof(Device1))]
тогда это работает, но я хочу написать массив нескольких типов устройств.
2 ответа
Вы должны добавить XmlIncludeAttribute для каждого подкласса, который вы хотите быть доступным в классе XMLDevicesContainer.
[XmlRoot(ElementName = "Devices")]
[XMLInclude(typeof(Device1))]
[XMLInclude(typeof(Device2))]
public class XMLDevicesContainer
{
:
}
Объявите свой XmlSerializer
следующее:
XmlSerializer xs = new XmlSerializer(typeof(obj), extraTypes);
У меня была та же проблема с веб-сервисом WCF, который я реализовал ранее. я имел (object obj)
в качестве параметра, и я объявлял XmlSerializer
лайк new XmlSerializer(typeof(object))
, который не был известен статически. Меняя его на new XmlSerializer(obj.GetType())
решил это.