简体   繁体   中英

xml serialization and Inherited Types

I got the error "{"The type Device1 was not expected. Use the XmlInclude or SoapInclude attribute to specify types that are not known statically."}"

Currently I have:

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;
        }
    }
}

and i am doing:

        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) });

serializer does:

   public static void Serialize<T>(T obj, XmlWriter writer, Type[] extraTypes)
    {
        XmlSerializer xs = new XmlSerializer(typeof(T), extraTypes);
        xs.Serialize(writer, obj);
    }

I fall on the last line in the serializer method (xs.Serialize) on the error: "{"The type Device1 was not expected. Use the XmlInclude or SoapInclude attribute to specify types that are not known statically."}"

I tried to write XmlInclude on the Device class. not helped. If I change the line

    [XmlArrayItem("Device", typeof(Device))] 

to be

     [XmlArrayItem("Device", typeof(Device1))]

then it works, but I want to write array of multiple Device types.

You must add the XmlIncludeAttribute for each subclass you want to be available on the XMLDevicesContainer class.

[XmlRoot(ElementName = "Devices")]
[XMLInclude(typeof(Device1))]
[XMLInclude(typeof(Device2))]
public class XMLDevicesContainer
{
:
}

Declare your XmlSerializer as follows:

XmlSerializer xs = new XmlSerializer(typeof(obj), extraTypes);

I had the same problem with a WCF webservice i implemented previously. I had (object obj) as a parameter & I was declaring my XmlSerializer like new XmlSerializer(typeof(object)) , which wasn't known statically. Changing it to new XmlSerializer(obj.GetType()) solved it.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM