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()) решил это.

Другие вопросы по тегам