How to serialize a collection of a base type and view specific types in readable XML

I have a list that is populated with objects of various specific types that are subclass of BaseType

I am using WCF DataContractSerializer

<Children> <BaseType xmlns:d3p1="http://schemas.datacontract.org/2004/07/Tasks" i:type="d3p1:ConcreteTypeA"></BaseType> <BaseType xmlns:d3p1="http://schemas.datacontract.org/2004/07/Tasks" i:type="d3p1:ConcreteTypeB"></BaseType> </Children> 

Is there any way to get this to create

 <Children> <ConcreteTypeA/> <ConcreteTypeB/> </Children> 

?

The real goal is to allow users to generate some XML for loading into memory, and skill level users who request the source XML will not be successful.

+4
source share
1 answer

DataContractSerializer is not intended to control output. It is designed for quick, implicit and simple class attribute using.

What you need is an XmlSerializer. This gives you more control over XML output.

Note that in my example below, I have pointed out many things that could be inferred from property names, but just to make it clear to you that you can override them in attributes. In fact, I think that this whole class would serialize just fine if all the attributes were removed and some KnownTypeAttributes were applied, but I did not test it. I don't know if this will give you the exact XML that you described (it will create the root element above Children), but hopefully this will lead you in the right direction.

Attributes That Control XML Serialization

 [XmlRoot(Namespace="")] public class MyClass { [XmlArray("Children")] [XmlArrayItem("ConcreteTypeA", typeof(ConcreteTypeA))] [XmlArrayItem("ConcreteTypeB", typeof(ConcreteTypeB))] public BaseType[] Children { get; set; } } public class BaseType { } public class ConcreteTypeA : BaseType { } public class ConcreteTypeB : BaseType { } 

EDIT: I just tested and created something very close to what you were looking for.

 void Main() { var mc = new MyClass(); mc.Children = new BaseType[] { new ConcreteTypeA(), new ConcreteTypeB(), new ConcreteTypeA(), new ConcreteTypeB() }; var serializer = new XmlSerializer(typeof(MyClass)); using ( var str = new StringWriter() ) { serializer.Serialize(str, mc); str.ToString().Dump(); } } 

... produces ... (useless xmlns removed from above)

 <MyClass> <Children> <ConcreteTypeA /> <ConcreteTypeB /> <ConcreteTypeA /> <ConcreteTypeB /> </Children> </MyClass> 
+7
source

Source: https://habr.com/ru/post/1306534/


All Articles