Serializing a <T> List in XML with Inheritance

I am having trouble trying to serialize my object to XML. The problem occurs when you try to serialize the Profiles property, which is an element of the profile list. Profile is my own type. The profile type should ideally be abstract, but this is not the case, since XML serialization requires ctor without parameters. The Profiles property contains elements of the type "IncomeProfile", "CostProfile", "InvestmentProfile", etc. Which, of course, are inherited from the profile.

As I read, serializing this is not supported initially, since XmlIncludeAttribute only allows one inherited type. I.e.

[XmlInclude(typeof(IncomeProfile))] public List<Profile> Profiles { get; set; } 

What is the best practice for solving this problem? I tried different solutions using IXmlSerializable and reflection, however I cannot deserialize each profile to the correct type (they all end using the ReadXml (XmlReader reader) method of type Profile, although the Visual Studio debugger says the type of the object is "IncomeProfile" or "CostProfile". This is my current deserialization code that deserializes xml into three Profile objects, instead of two IncomeProfile and one CostProfile:

 while(reader.MoveToContent() == XmlNodeType.Element && reader.LocalName == "Profile") { String type = reader["Type"]; var project = (Profile)Activator.CreateInstance(Type.GetType(type)); project.ReadXml(reader); reader.Read(); this.Profiles.Add(p2); } 

Any thoughts or suggestions are greatly appreciated!

+4
source share
2 answers

You are allowed to use several include attributes - although they are most often set against the type itself:

 using System; using System.Collections.Generic; using System.Xml.Serialization; [XmlInclude(typeof(IncomeProfile))] [XmlInclude(typeof(CostProfile))] [XmlInclude(typeof(InvestmentProfile))] public class Profile { public string Foo { get; set; } } public class IncomeProfile : Profile { public int Bar { get; set; } } public class CostProfile : Profile { } public class InvestmentProfile : Profile { } static class Program { static void Main() { List<Profile> profiles = new List<Profile>(); profiles.Add(new IncomeProfile { Foo = "abc", Bar = 123 }); profiles.Add(new CostProfile { Foo = "abc" }); new XmlSerializer(profiles.GetType()).Serialize(Console.Out, profiles); } } 
+10
source

You just need to use a few [XmlInclude] attributes. It works well.

+3
source

All Articles