Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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()
    {
    }
........
like image 236
user2130951 Avatar asked Oct 23 '13 09:10

user2130951


People also ask

What is the correct way of using XML serialization?

As with the CreatePo method, you must first construct an XmlSerializer, passing the type of class to be deserialized to the constructor. Also, a FileStream is required to read the XML document. To deserialize the objects, call the Deserialize method with the FileStream as an argument.

What is serializing XML?

XML serialization is the process of converting XML data from its representation in the XQuery and XPath data model, which is the hierarchical format it has in a Db2® database, to the serialized string format that it has in an application.

Can we serialize list in C#?

In C# programs we often need to read and write data from the disk. A List can be serialized—here we serialize (to a file) a List of objects.

What is XML serialization in C#?

XML serialization is the process of converting an object's public properties and fields to a serial format (in this case, XML) for storage or transport. Deserialization re-creates the object in its original state from the XML output.


1 Answers

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
like image 144
DeanOC Avatar answered Oct 03 '22 09:10

DeanOC