?
Solved

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

Posted on 2008-10-21
4
Medium Priority
?
2,881 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 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 2000 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

Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

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

This article will show, step by step, how to integrate R code into a R Sweave document
When we want to run, execute or repeat a statement multiple times, a loop is necessary. This article covers the two types of loops in Python: the while loop and the for loop.
The goal of the video will be to teach the user the concept of local variables and scope. An example of a locally defined variable will be given as well as an explanation of what scope is in C++. The local variable and concept of scope will be relat…
This video will show you how to get GIT to work in Eclipse.   It will walk you through how to install the EGit plugin in eclipse and how to checkout an existing repository.
Suggested Courses

777 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