How to XML serialize a Generic List<T> containing multiple Types derived from a base class T

Locked How to XML serialize a Generic List<T> containing multiple Types derived from a base class T

  • Wednesday, March 14, 2007 10:12 PM
     
     
    I need to serialize to XML a datastructure based on Generics such as List<T>. The problem arises in that I want T to be a base class for multiple derived classes. When I try to serialize this I cannot get the derived classes to be serialized, only the base Class are serialized.

    Eg;

    [Serialize]
    Class Node{
       private string n_info;
    }

    Class Node_A : Node {
       private string a_info;
    }

    Class node_B : Node {
      private string b_info;
    }

    List<Node> list = new List<Node>();
    list.Add(new Node_A());
    list.Add(new Node_B());

     XmlSerializer serializer = new XmlSerializer(typeof(List<Node>),
                        new Type[] { typeof(Node_A), typeof(Node_B) });

    FileStream fstream = new FileStream("ListData.xml", FileMode.Create, FileAccess.Write, FileShare.None);
    serializer.Serialize(fstream, list);
    fstream.Close();

    This runs but only serializes the Node Base Class attributes.

All Replies

  • Friday, March 23, 2007 9:31 AM
     
     Answered

    A bit late maybe, but...have you tried the XmlInclude attribute?
    You need to set an XmlInclude entry on the base class for each subclass. In your example it would be:

    ...
    [Serializable]
    [XmlInclude(Node_A)]
    [XmlInclude(Node_B)]
    Class Node{
       private string n_info;
    }
    ...

    Ugly - yes, but there you go...

    //Carl

  • Friday, March 23, 2007 1:18 PM
     
     Answered
    Just a quick point but all your members are marked 'private' and you can only serialize public members with XmlSerializer.  Are you sure that this is not connected to your problem?
  • Wednesday, March 28, 2007 9:04 AM
     
     Answered

    I got it working as follows..

     

    // Create a sample List with test data

    List<Node> list = new List<Node>();

    list.Add(new AppNode("app1"));

    list.Add(new DbNode("db1"));

     

    // Serialise the list

    XmlSerializer serializer = new XmlSerializer(typeof(List<Node>), new Type[] { typeof(AppNode), typeof(DbNode) });

    FileStream fstream = new FileStream("List-Node.xml", FileMode.Create, FileAccess.Write, FileShare.None);

    serializer.Serialize(fstream, list);

    fstream.Close();

     

    // Deserialise the list

    fstream = new FileStream("List-Node.xml.xml", FileMode.Open, FileAccess.Read, FileShare.None);

    list.Clear();

    list = (List<Node>)serializer.Deserialize(fstream);

    fstream.Close();

     

    The Node, AppNode and DBNode are defined as follows:-

     

    [Serializable]

    public class Node

    {

        public Node() {}    // Required for Serialization

     

        public Node(string nm)

        {

            Name = nm;

        }

     

        private string m_name = "";

        public string Name

        {

            get { return m_name; }

            set { m_name = value; }

         }

    }

     

    [Serializable]

    public class AppNode : Node

    {

         public AppNode() : base()  {  }     // Required for Serialization

     

         public AppNode(string nm) : base(nm)

         {

                AppInfo = "Some info about app";

         }

     

         private string m_appInfo;

         public string AppInfo

         {

             get { return m_appInfo; }

             set { m_appInfo = value; }

         }

    }

     

    [Serializable]

    public class DbNode : Node

    {   

        public DbNode() : base()    {}       // Required for Serialization

     

        public DbNode(string nm) : base(nm)

        {

            DbInfo = "Some info about database";

        }

     

        private string m_dbInfo;

        public string DbInfo

        {

            get { return m_dbInfo; }

           set { m_dbInfo = value; }

        }

    }