Solved

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

Posted on 2008-10-21
4
2,850 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

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Windows Script Host (WSH) has been part of Windows since Windows NT4. Windows Script Host provides architecture for building dynamic scripts that consist of a core object model, scripting hosts, and scripting engines. The key components of Window…
Calculating holidays and working days is a function that is often needed yet it is not one found within the Framework. This article presents one approach to building a working-day calculator for use in .NET.
The goal of this video is to provide viewers with basic examples to understand and use switch statements in the C programming language.
The viewer will learn how to implement Singleton Design Pattern in Java.

895 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

14 Experts available now in Live!

Get 1:1 Help Now