Solved

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

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

The Ultimate Checklist to Optimize Your Website

Websites are getting bigger and complicated by the day. Video, images, custom fonts are all great for showcasing your product/service. But the price to pay in terms of reduced page load times and ultimately, decreased sales, can lead to some difficult decisions about what to cut.

Question has a verified solution.

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

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.
Performance in games development is paramount: every microsecond counts to be able to do everything in less than 33ms (aiming at 16ms). C# foreach statement is one of the worst performance killers, and here I explain why.
This theoretical tutorial explains exceptions, reasons for exceptions, different categories of exception and exception hierarchy.
The viewer will learn how to clear a vector as well as how to detect empty vectors in C++.

724 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