Solved

C#: serialize an object, which is a list of objects

Posted on 2008-10-21
4
2,848 Views
Last Modified: 2012-08-14
I have a c# project that contains 3 entities:

- Picture
- PictureList (which contains Pictures)
- PictureBook (which contains one PictureList)

If I serialize the picture, the Element name is correct (from XmlRoot):
<THE_PICTURE ID="pic1" USER="firepol" />

If I serialize the PictureBook, all the elements are serialized correctly (as XmlArray is followed by XmlArrayItem, which tells the name the item should have, overriding -if different- the "original" one):
<PICTURE_BOOK BOOK_ID="MyBook"><PICTURE_LIST><THE_PICTURE ID="pic1" USER="firepo
l" /></PICTURE_LIST></PICTURE_BOOK>

If I serialize the PictureList, the child element that should be called "THE_PICTURE", doesn't get the name as written in the XmlRoot. It gets it from the class name: "Picture".
<PICTURE_LIST><Picture ID="pic1" USER="firepol" /></PICTURE_LIST>

should be:

<PICTURE_LIST><THE_PICTURE ID="pic1" USER="firepol" /></PICTURE_LIST>

I need to have the PictureList class for some other reasons (I reproduced this demo from a more complex situation at work, just to give you some usable code).

Please tell me how can I modify the PictureList class (if that one is the one to be modified) or tell me what to do so that when I serialize a PictureList object I will get it as supposed to be.

See snippet code.
//////////////////////////////////////// Picture.cs

 

using System;

using System.Collections.Generic;

using System.Xml.Serialization;

using System.Text;

 

namespace MyDemo.Entities

{

    [Serializable()]

    [XmlRoot("THE_PICTURE")]

    public class Picture

    {

 

        // Id

        private string m_Id;

        [XmlAttribute("ID")]

        public string Id

        {

            get { return m_Id; }

            set { m_Id = value; }

        }

 

        // User

        private string m_User;

        [XmlAttribute("USER")]

        public string User

        {

            get { return m_User; }

            set { m_User = value; }

        }

 

        // Default Constructor

        public Picture()

        {

        }

 

    }

}

 

 

//////////////////////////////////////// PictureList.cs

 

using System;

using System.Collections.Generic;

using System.Xml.Serialization;

using System.Text;

 

namespace MyDemo.Entities

{

    [Serializable()]

    [XmlRoot("PICTURE_LIST")]

    public class PictureList : List<Picture>

    {

        public PictureList()

        {

        }

    }

}

 

 

//////////////////////////////////////// PictureBook.cs

 

using System;

using System.Collections.Generic;

using System.Xml.Serialization;

using System.Text;

 

namespace MyDemo.Entities

{

    [Serializable()]

    [XmlRoot("PICTURE_BOOK")]

    public class PictureBook

    {

        // BookId

        private string m_BookId;

        [XmlAttribute("BOOK_ID")]

        public string BookId

        {

            get { return m_BookId; }

            set { m_BookId = value; }

        }

 

        // PictureList

        private PictureList m_PictureList;

        [XmlArray("PICTURE_LIST")]

        [XmlArrayItem("PICTURE")]

        public PictureList PictureList

        {

            get { return m_PictureList; }

            set { m_PictureList = value; }

        }

 

    }

}

 

//////////////////////////////////////// EntityTool.cs

 

using System;

using System.Collections.Generic;

using System.Text;

using System.Xml.Serialization;

using System.IO;

using System.Xml;

 

namespace MyClasses

{

    public class EntityTool

    {

// This is the serializer

        public static string SerializeObject(object objectToSerialize)

        {

            if (objectToSerialize == null)

                throw new ArgumentNullException("The serializable object cannot be null", "objectToSerialize");

 

            XmlSerializer serializer = new XmlSerializer(objectToSerialize.GetType());

            MemoryStream stream = new MemoryStream();

            XmlSerializerNamespaces ns = new XmlSerializerNamespaces();

            ns.Add("", "");

 

            serializer.Serialize(stream, objectToSerialize, ns);

            stream.Position = 0;

            StreamReader sm = new StreamReader(stream);

            string result = sm.ReadToEnd();

            stream.Close();

            //workaround to remove XmlDeclaration

            XmlDocument xmlResult = new XmlDocument();

            xmlResult.LoadXml(result);

            if (xmlResult.FirstChild.NodeType == XmlNodeType.XmlDeclaration)

                xmlResult.RemoveChild(xmlResult.FirstChild);

            return xmlResult.InnerXml;

 

        }

    }

}

 

//////////////////////////////////////// ConsoleTest.cs

 

using System;

using System.Collections.Generic;

using System.Text;

using MyDemo.Entities;

using MyClasses;

 

namespace ConsoleTest

{

 

//This is a console application, to check the serialized objects.

    class Program

    {

        static void Main(string[] args)

        {

            // Picture

 

            Picture pic1 = new Picture();

            pic1.Id = "pic1";

            pic1.User = "firepol";

 

            // Serialize Picture

 

            string pic1XML = EntityTool.SerializeObject(pic1);

            Console.WriteLine(pic1XML);

 

            // PictureList

 

            PictureList myFav = new PictureList();

            myFav.Add(pic1);

 

            // Serialize PictureList

 

            string myFavXML = EntityTool.SerializeObject(myFav);

            Console.WriteLine(myFavXML);

 

            // Book

 

            PictureBook myBook = new PictureBook();

            myBook.BookId = "MyBook";

            myBook.PictureList = myFav;

 

            // Serialize Book

 

            string myBookXML = EntityTool.SerializeObject(myBook);

            Console.WriteLine(myBookXML);

 

        }

    }

}

Open in new window

0
Comment
Question by:firepol
  • 2
  • 2
4 Comments
 
LVL 3

Expert Comment

by:torrie01
ID: 22780857
The problem is on line 87 where you say [XmlArrayItem("PICTURE")] - this is what determines how the PictureList items are written to the XML.  Change it to [XmlArrayItem("THE_PICTURE")] and it should fix your problem.
0
 
LVL 2

Author Comment

by:firepol
ID: 22788869
torrie01: I just modified my demo while i was writing the question in EE. At line 87 I already have "THE_PICTURE". Anyway, line 87 is inside the PictureBook Entity, which is serialized correctly.

My problem is when I try to serialize the PictureList Entity, where I get:

<PICTURE_LIST><Picture ID="pic1" USER="firepol" /></PICTURE_LIST>

instead of

<PICTURE_LIST><THE_PICTURE ID="pic1" USER="firepol" /></PICTURE_LIST>.

It seems that by serializing a class, which is a list of objects (in my case, a list of "Picture") even if the entity Picture has defined the XmlRoot: [XmlRoot("THE_PICTURE")] it is serialized by getting as default the class name, which in my case it's "Picture"... very strange...  I guess I should add something in the PictureList entity, but what?

Thanks for helping me... try to create something similar or use my demo code, and see ;-)
0
 
LVL 3

Accepted Solution

by:
torrie01 earned 500 total points
ID: 22789401
Sorry about that.  On Line 11, use "XmlType" instead of "XmlRoot" and you should see the results you're looking for.
0
 
LVL 2

Author Closing Comment

by:firepol
ID: 31508514
Thank you very much mate!! I knew it was a small change like that, you can't imagine how much time i lost because of this. Thanks for your precious answer, have a nice weekend and keep on helping other people.

Cheers,

Paolo
0

Featured Post

IT, Stop Being Called Into Every Meeting

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

Join & Write a Comment

Go is an acronym of golang, is a programming language developed Google in 2007. Go is a new language that is mostly in the C family, with significant input from Pascal/Modula/Oberon family. Hence Go arisen as low-level language with fast compilation…
Exception Handling is in the core of any application that is able to dignify its name. In this article, I'll guide you through the process of writing a DRY (Don't Repeat Yourself) Exception Handling mechanism, using Aspect Oriented Programming.
The goal of this video is to provide viewers with basic examples to understand and use conditional statements in the C programming language.
The viewer will learn how to implement Singleton Design Pattern in Java.

706 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

19 Experts available now in Live!

Get 1:1 Help Now