23

I'm having a situation here, I need my class to be inherited from List<ItemType>, but when I do this XmlSerializer does not serialize any property or field declared in my class, the following sample demonstrates:

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
        DoSerialize();
    }
    private void DoSerialize()
    {
        MyClass obj = new MyClass();
        obj.Add(1);
        obj.Add(2);
        obj.Add(3);
        XmlSerializer s = new XmlSerializer(typeof(MyClass));
        StringWriter sw = new StringWriter();
        s.Serialize(sw, obj);
    }
}
[Serializable]
[XmlRoot]
public class MyClass : List<int>
{
    public MyClass()
    {
    }
    int myAttribute = 2011;
    [XmlAttribute]
    public int MyAttribute
    {
        get
        {
            return myAttribute;
        }
        set
        {
            myAttribute = value;
        }
    }
}

the resulting XML:

<?xml version="1.0" encoding="utf-16"?>
<ArrayOfInt xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <int>1</int>
  <int>2</int>
  <int>3</int>
</ArrayOfInt>
7
  • 1
    This is one of many reasons you generally shouldn't subclass List. Commented Feb 21, 2011 at 17:29
  • @kirk: Yeah, I think also the same, but this time I have to, I didn't start the project, it's like this and I have to do serialization on it Commented Feb 21, 2011 at 17:36
  • @Kirk not disagreeing with that principle, but here (per the link in @driis answer) the problem is actually that implementing IEnumerable at all means your own properties don't get serialised! Which seems pretty harsh... Commented Feb 21, 2011 at 17:45
  • possible duplicate of XmlSerializer doesn't serialize everything in my class Commented Feb 21, 2011 at 17:46
  • @AakashM Sorry for the duplicate, I searched but didn't find it, perhaps I was using the wrong kewords Commented Feb 21, 2011 at 17:56

2 Answers 2

27

This is by design. I don't know why this decision was made, but it is stated in the documentation:

  • Classes that implement ICollection or IEnumerable. Only collections are serialized, not public properties.

(Look under "Items that can be serialized" section). Someone has filed a bug against this, but it won't be changed - here, Microsoft also confirms that not including the properties for classes implementing ICollection is in fact the behaviour of XmlSerializer.

A workaround would be to either:

  • Implement IXmlSerializable and control serialization yourself.

or

  • Change MyClass so it has a public property of type List (and don't subclass it).

or

  • Use DataContractSerializer, which handles this scenario.
Sign up to request clarification or add additional context in comments.

3 Comments

I thought that would be the answer but I was just wanted to make sure, I asked cuz I couldn't find it in the documentation, Thank you
Hi, found this question here like 5 years later. Since this is still a problem - how would you do that with DataContractSerializer?
Have you tried to solve it with DataContractSerializer. Can't get it working (stackoverflow.com/questions/55301839/…)
7

Here's a though for you to consider.

You can have a class that is a container class like this:

class ContainerObject
{
     public int MyNewProperty { get; set; }

     [XmlElement("")]
     public List<int> MyList { get; set; }
}

The trick is to have XmlElement name = "" above the List element.

When this is serialized into xml, you will have:

<ContainerObject>
   <MyNewProperty>...</MyNewProperty>

   <int>...</int>
   <int>...</int>

</ContainerObject>

If you like, you can also create another class for items in a list

 class MyItem
 {
     public int MyProperty {get;set;} 

 } 

and then instead of having List of ints, have a List of MyItems.

This was you control XmlElement name of every item in a list.

I hope this was helpful.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.