Oliver Oliver - 14 days ago 6
C# Question

Serializing a List hold an interface to XML

I have been reading around but I have not come across a solution to my problem

I am currently working with a Business Object that will hold all my data and we need to convert this object to and from XML.

My object holds a list of Actions (List...), but there are 2 action types (for now).
I have to action types SimpleAction and CompositeAction, and they both inherit from IAction allowing them to both be held in the Actions list.

Now you can probably see the problem as Interfaces cannot be serialized as they hold no data.

How, with maybe some sample code, do I write a Class or Serializer that gets that object type and performs then serializes object with the correct type?

Some code:

[XmlArray("Actions")]
public List<IAction> Actions { get; set; }

public interface IAction
{
int ID { get; set; }

ParameterCollection Parameters { get; set; }

List<SectionEntity> Validation { get; set; }

TestResultEntity Result { get; set; }

string Exception { get; set; }
}

[XmlType("A")]
public class SimpleActionEntity : IAction
{
#region IAction Members

[XmlAttribute("ID")]
public int ID { get; set; }

[XmlIgnore]
public ParameterCollection Parameters { get; set; }

[XmlIgnore]
public List<SectionEntity> Validation { get; set; }

[XmlIgnore]
public TestResultEntity Result { get; set; }

[XmlElement("Exception")]
public string Exception { get; set; }

#endregion
}


Any help would be greatly appreciated. :)

Answer

Ok I have created a solution that I feels does what I want pretty well.

What I did is rather than holding

 [XmlArray("Actions")]
 public List<IAction> Actions { get; set; }

I decided to create an ActionsCollection class that handled the List BUT also allowed me to use IXMLSerializable to override the ReadXml and WriteXML methods so that I could handle the way the list is Serialized and Deserialized.

[XmlElement("Actions")]
public ActionCollection Actions { get; set; }

public class ActionCollection: CollectionBase, IXmlSerializable
{
    #region IList Members
      ...
    #endregion

    #region ICollection Members
     ...
    #endregion

    #region IEnumerable Members
    ...
    #endregion

    #region IXmlSerializable Members

    public System.Xml.Schema.XmlSchema GetSchema()
    {
        return null;
    }

    public void ReadXml(System.Xml.XmlReader reader)
    {
       //TODO
    }

    public void WriteXml(System.Xml.XmlWriter writer)
    {
        foreach (IAction oAction in List)
        {       
                XmlSerializer s = new XmlSerializer(oAction.GetType());
                s.Serialize(writer, oAction);
        }
    }

    #endregion
}
Comments