简体   繁体   中英

XML serialization of List<Object>

I am failing to save a list of Animals to disk with XML serialization.

I am getting Exception:Thrown: "The type AnimalLibrary.Animals.Mammals.Dog was not expected. Use the XmlInclude or SoapInclude attribute to specify types that are not known statically." (System.InvalidOperationException)

If I try the commented code with the "Dog" it will work just as expected and the XML is generated. But the same dog sent in as the only element in the List does not work.

    [XmlElement("animalList")]
    public List<Animal> animalList = new List<Animal>();

public bool SaveBinary(string fileName)
    {
        Mammals.Dog dog = (Mammals.Dog)animalList[0];

        //IObjectSerializer<Mammals.Dog> obj = new XMLObjectSerializer<Mammals.Dog>();
        IObjectSerializer<List<Animal>> obj = new XMLObjectSerializer<List<Animal>>();

        bool saved = obj.SaveFile(fileName, animalList);
        if (saved)
            return true;

        return false;
    }

XML serializer

public bool SaveFile(string fileName, T objectToSerialize)
    {
        try
        {
            //Will overwrite old file
            XmlSerializer mySerializer = new XmlSerializer(typeof(T));

            StreamWriter myWriter = new StreamWriter(fileName);
            mySerializer.Serialize(myWriter, objectToSerialize);
            myWriter.Close();
        }
        catch (IOException ex)
        {
            Console.WriteLine("IO Exception ", ex.Message);
            return false;
        }
        return true;
    }

Files for inheritance of the dog. There are no xml tags inside the classes.

[XmlRoot(ElementName="Animal")]
public abstract class Animal : IAnimal
{

    /// <summary>
    /// Id of animal
    /// </summary>
    private string id;
    public string ID

........

[XmlRoot(ElementName = "Animals")]
public abstract class Mammal : Animal
{


   public int NumberofTeeth { get; set; }

........

[XmlRoot(ElementName="Dog")]
public class Dog : Mammal
{

    /// <summary>
    /// Constructor - Create an instance of a Dog
    /// </summary>
    public Dog()
    {
    }
........

If you want to have a list of objects and serialize them as a list of the base type, then you need to tell the serializer what sort of concrete types are possible.

So if you wanted to put a Dog and a Cat object into your Animal list you would need to add markup to the Animal class as follows

[XmlInclude(typeof(Cat))]
[XmlInclude(typeof(Dog))]
[XmlRoot(ElementName="Animal")]
public abstract class Animal : IAnimal

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