I wrote a small console application to test if this was possible and it turns out all you need is an XmlInclude attribute on the base type of the sub-types you are serializing.
In the following example Ninja and Customer inherit from Person, Person is decorated with the XmlInclude attribute for both Ninja and Customer.
class Program
{
static void Main(string[] args)
{
XmlSerializer serializer = new XmlSerializer(typeof(Stuff));
Stuff stuff = new Stuff()
{
People = new List<Person>()
{
new Person() { Name = "<b>Bob</b>", Type="Person" },
new Ninja() { Name = "Hiro", Type="Ninja", Weapon = "Shuriken" },
new Customer() { Name = "Fred", Type = "Customer", CustomerId = "1234"}
}
};
serializer.Serialize(Console.Out, stuff);
}
}
public class Stuff
{
public List<Person> People { get; set; }
}
[XmlInclude(typeof(Ninja)), XmlInclude(typeof(Customer))]
public class Person
{
public string Type { get; set; }
public string Name { get; set; }
}
public class Ninja : Person
{
public string Weapon { get; set; }
}
public class Customer : Person
{
public string CustomerId { get; set; }
}