How to serialize derived classes in a Xml?
10,057
You have to tell the serializer about the derived types
[XmlInclude(typeof(FooA))]
[XmlInclude(typeof(FooB))]
public abstract class Foo
{
public abstract int X { get; set; }
}
This is one of the choice .Net exceptions that are truly helpful. If you look at the InnerException, you will see
The type FooA was not expected. Use the XmlInclude or SoapInclude attribute to specify types that are not known statically.
UPDATE
Based on your comment about many derived types in different modules, you can also specify derived types at runtime when creating the serializer rather than at compile time:
How to add XmlInclude attribute dynamically
Author by
Darf Zon
Updated on June 04, 2022Comments
-
Darf Zon almost 2 years
Imagine this is my scenario:
public abstract class Foo { public abstract int X { get; set; } } public class FooA : Foo { public override int X { get; set; } public int Y { get; set; } } public class FooB : Foo { public override int X { get; set; } public int Z { get; set; } }
This is a service where I've got some objects to serialize.
public class FooService { public List<Foo> GetModels() { return new List<Foo>() { new FooA() { X = 3, Y = 6 }, new FooB() { X = 5, Z = 10 } }; } }
And this is the method where I can't serialize my objects, it throws an exception. I want to serialize derived classes.
private void SerializeObjects() { FooService service = new FooService(); var a = service.GetModels(); XmlSerializer x = new XmlSerializer(a.GetType()); TextWriter writer = new StreamWriter("A.xml"); x.Serialize(writer, a); writer.Close(); }
-
dee-see about 12 yearsWhat is the exception? What have you tried?
-
Eric J. about 12 yearsWhat's the exception text? I bet it's complaining about known types and telling you what to do about it.
-
Darf Zon about 12 years@Vache this is my error: There was an error generating the XML document.
-
dreza about 12 yearsThere's no XML Attribute declarations on any of those classes. You have to tell the serializer what to serialise by decorating properties and attributes of Foo, FooA, FooB etc
-
Eric J. about 12 yearsAnd the inner exception tells you to
"The type FooA was not expected. Use the XmlInclude or SoapInclude attribute to specify types that are not known statically."
:-) -
Darf Zon about 12 years@EricJ. It works :), allow me to make clear my situation. I've got a library where it has ´Foo´, and another modules contains FooA and FooB. I mean, I need to create many modules and I don't prefer put those Includes.. what might I do?
-
L.B about 12 years@DarfZon Use some other serializers like Json.Net
-
Eric J. about 12 years@L.B: Json.Net can handle types that are not statically known? DataContractSerializer cannot... would surprise me if Json.Net can.
-
Eric J. about 12 years@DarfZon: Added more info to the answer based on "many modules"
-
L.B about 12 years@EricJ. This is the output
[{"X":3,"Y":6},{"X":5,"Z":10}]
ofJsonConvert.SerializeObject(service.GetModels())
-