Want to protect your cyber security and still get fast solutions? Ask a secure question today.Go Premium

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 2949
  • Last Modified:

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

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
firepol
Asked:
firepol
  • 2
  • 2
1 Solution
 
torrie01Commented:
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
 
firepolAuthor Commented:
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
 
torrie01Commented:
Sorry about that.  On Line 11, use "XmlType" instead of "XmlRoot" and you should see the results you're looking for.
0
 
firepolAuthor Commented:
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

Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

  • 2
  • 2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now