Search code examples
c#ixmlserializable

Custom XmlSerialization for nested / child objects


I have a scenario in which I have a class Resource which has two other classes nested in it; Action and ResourceURL. I need to write custom xmlserializer for Resource and Action but not for ResourceURL. I implemented IXmlSerializable for both.

The problem is, when Resource is serialized, i call the Action.WriteXML(XmlWriter) to get the serialized form of Action, but i can't get serialized form of ResourceURL. The tags become all messed up and it also adds an tag.

So how do i serialize an object which has customer serilzation for some nested objects but not for others?


Solution

  • Here is a sample WriteXml method:

        void IXmlSerializable.WriteXml(XmlWriter writer)
        {
            // Simple string value:
            writer.WriteAttributeString("Name", this.Name);
    
            // Object without IXmlSerializable implementation:
            writer.WriteStartElement("NonCustomObject");
            new XmlSerializer(NonCustomObjectType).Serialize(writer, this.NonCustomObject);
            writer.WriteEndElement();
    
            // Object with IXmlSerializable implementation:
            writer.WriteStartElement("CustomObject");
            (this.CustomObject as IXmlSerializable).WriteXml(writer);
            writer.WriteEndElement();
        }
    

    Here is a corresponding ReadXml method:

        void IXmlSerializable.ReadXml(XmlReader reader)
        {
            // Simple string value
            this.Name = reader.GetAttribute("Name");
    
            // Object without IXmlSerializable implementation here:
            reader.ReadStartElement();
            if (reader.Name == "NonCustomObject")
            {
                reader.ReadStartElement();
                this.NonCustomObject = new XmlSerializer(NonCustomObjectType).Deserialize(reader);
                reader.ReadEndElement();
            }
    
            // Object with IXmlSerializable implementation here:
            reader.ReadStartElement();
            if (reader.Name == "CustomObject")
            {   
                (this.CustomObject as IXmlSerializable).ReadXml(reader);
                reader.ReadEndElement();
            }
        }