XML serialization with derived class [problem]

Dec 19 2011 2:15 AM
Hi I've recently been trying out XML serialization via the following MSDN article: http://msdn.microsoft.com/en-us/library/2baksw0z(v=vs.71).aspx

Specifically, where it sais: "Serializing Derived Classes".

As you can see my code is very similar:


<?xml version="1.0" encoding="utf-8"?>
<questions  xmlns="http://www.foobar.com/questions">
  <question>
    <text>How many pink elephants do you see?</text>
    <answers>
      <answer type="derived">
        <text>eight</text>
        <male>2</male>
      </answer>
      <answer type="derived">
        <text>nine</text>
        <male>3</male>
      </answer>
    </answers>
  </question>
</questions>


    [Serializable]
    public class Question2
    {
        protected ArrayList _answers;


        public Question2()
        {
            _answers = new ArrayList();
        }


        [XmlArray(ElementName = "answers")]
        [XmlArrayItem(ElementName = "answer", Type = typeof(Base)), XmlArrayItem(Type = typeof(Derived))]
        public ArrayList Answers
        {
            get { return _answers; }
            set { _answers = value; }
        }
    }


    [Serializable]
    public class Base
    {
        private string _answer;


        [XmlElement(ElementName = "text", DataType = "string")]
        public string AnswerString
        {
            get { return _answer; }
            set { _answer = value; }
        }
    }


    [Serializable]
    public class Derived : Base
    {
        ushort _maleModifier;


        [XmlElement(ElementName = "male", DataType = "unsignedShort")]
        public ushort MaleModifier
        {
            get { return _maleModifier; }
            set { _maleModifier = value; }
        }
    }

I've run into a very specific problem. Almost everything works fine, I'm able to deserialize the XML into my container class (not present), 
but i'm not getting any derived info, only base.

If I reverse the order for the following line of code it works: 
 [XmlArrayItem(ElementName = "answer", Type = typeof(Base)), XmlArrayItem(Type = typeof(Derived))]
to:
        [XmlArrayItem(ElementName = "answer", Type = typeof(Derived)), XmlArrayItem(Type = typeof(Base))]

I can remove Type = typeof(base) and that also works. But I don't want to do either of these because I want to separate my class structure from the XML. Plus, according to MSDN:

"Another use of the XmlArrayItemAttribute is to allow the serialization of derived classes. For example, another class named Manager that derives from Employee can be added to the previous example. If you do not apply the XmlArrayItemAttribute, the code will fail at run time because the derived class type will not be recognized. To remedy this, apply the attribute twice, each time setting the XmlArrayItemAttribute.Type property for each acceptable type (base and derived)."

I've done that. Apparently there's more to it. Any help/explanation would be appreciated.



Answers (1)