Search code examples
c#xmlxml-serializationxmlserializer

XML Serialize for inherited objects C#


I have the following XML Scenario:

<al2:Dispatch xmlns:al1="al:1.0.0" xmlns:al2="al:2.0.0">

    <al2:MsgIdentificator>0001</al2:MsgIdentificator>

    ..

    <al1:DispatchReceiverGroup>

        <al2:Receiver>

            <al1:ANumberIdentificator>100001</al1:ANumberIdentificator>
            <al1:BNumberIdentificator>1000000001</al1:BNumberIdentificator>

        </al2:Receiver>

    </al1:DispatchReceiverGroup>

</al2:Dispatch>

So My Model is as follows:

    [Serializable]
    [XmlRoot(Namespace = "al:2.0.0", ElementName = "Dispatch")]
    public class BatchDistribution
    {
        [XmlElement(Namespace = "al:2.0.0", ElementName = "MsgIdentificator")]
        public string MessageIdentificator { get; set; }

        //CONFUSED HERE
        [XmlArray(Namespace = "al:1.0.0", ElementName = "DispatchReceiverGroup")]
        [XmlArrayItem(Namespace = "al:2.0.0", ElementName = "Receiver")]
        public List<DistributionReceiver> DistributionRecievers { get; set; }    
    }
}

So I want to have an optional amount of Elements of ANumberIdentificator and BNumberIdentificator elements. For this, I made a Base Class DistributionReceiver, which is inherited by DistributionReceiverA and DistributionReceiverB, such as follows:

    [Serializable]
    public class DistributionReceiver
    {
        [XmlElement(Namespace = "al:1.0.0")]    //note i dont assign value for Element name because it has to be decided by sub classes 
        public string NumberIdentificator{ get; set; }
    }

and the sub classes:

    [Serializable]
    public class DistributionRecieverA : DistributionReceiver
    {
        [XmlElement(Namespace = "al:1.0.0", ElementName = "ANumberIdentificator")]
        public new string ANumberIdentificator { get; set; }
    }

and the other

    [Serializable]
    public class DistributionRecieverB : DistributionReceiver
    {
        [XmlElement(Namespace = "al:1.0.0", ElementName = "BNumberIdentificator")]
        public new string BNumberIdentificator { get; set; }
    }

Problem is: I don't get serialized ANumberIdentificator and BNumberIdentificator.


Solution

  • Looks like the model is incorrect for ANumberIdentificator and BNumberIdentificator

    I have used xmltocsharp to convert the example XML and the model looked like

        [XmlRoot(ElementName = "Receiver", Namespace = "al:2.0.0")]
    public class Receiver
    {
        [XmlElement(ElementName = "ANumberIdentificator", Namespace = "al:1.0.0")]
        public List<string> ANumberIdentificator { get; set; }
        [XmlElement(ElementName = "BNumberIdentificator", Namespace = "al:1.0.0")]
        public List<string> BNumberIdentificator { get; set; }
    }
    
    [XmlRoot(ElementName = "DispatchReceiverGroup", Namespace = "al:1.0.0")]
    public class DispatchReceiverGroup
    {
        [XmlElement(ElementName = "Receiver", Namespace = "al:2.0.0")]
        public Receiver Receiver { get; set; }
    }
    
    [XmlRoot(ElementName = "Dispatch", Namespace = "al:2.0.0")]
    public class Dispatch
    {
        [XmlElement(ElementName = "MsgIdentificator", Namespace = "al:2.0.0")]
        public string MsgIdentificator { get; set; }
        [XmlElement(ElementName = "DispatchReceiverGroup", Namespace = "al:1.0.0")]
        public DispatchReceiverGroup DispatchReceiverGroup { get; set; }
        [XmlAttribute(AttributeName = "al1", Namespace = "http://www.w3.org/2000/xmlns/")]
        public string Al1 { get; set; }
        [XmlAttribute(AttributeName = "al2", Namespace = "http://www.w3.org/2000/xmlns/")]
        public string Al2 { get; set; }
    }
    

    I have used XmlSerializer to convert the XML to object

    XmlSerializer serializer = new XmlSerializer(typeof(Dispatch));
            using (TextReader reader = new StringReader(xmlstring))
            {
                //convert the xml to object
                Dispatch result = (Dispatch)serializer.Deserialize(reader);
            }
    

    And I am able to read A and B under Receiver

    Console.WriteLine(result.DispatchReceiverGroup.Receiver.ANumberIdentificator);
    
    Console.WriteLine(result.DispatchReceiverGroup.Receiver.BNumberIdentificator);