David
David

Reputation: 1841

C# Xml serialization of objects with IEnumerable

whenever I try to serialize an object that has an IEnumerable collection I get a big dirty error telling me it can't serialize it because it's an interface. Now I get why it's happening but it raises some other questions for me. Like if I intend on having collections within my objects AND I want to serialize them do I need to resort to

  1. Using List<>, CollectionBase, ReadOnlyCollectionBase in my objects.
  2. Making my objects implement the IXmlSerializable interface.
  3. Decorating my classes with horrible attributes.
  4. Writing my own serializer.

What is the best practice way to go?

Upvotes: 4

Views: 5124

Answers (2)

Marc Gravell
Marc Gravell

Reputation: 1062865

Speaking as a serializer author, I know exactly why it gets very hard to robustly work just from IEnumerable<T>, especially for "get-only" properties. You might try IList<T> (although it wouldn't amaze me if it wants a concrete type such as List<T>/T[]), but I suspect the real problem here is that you trying to use one model to do two things, and are unhappy at having to compromise to do it.

Fine: if you don't want to compromise your domain model, write a separate DTO model that is used for serialization, and just map between them. This is usually trivial, and will allow the serializer and the domain model to each excel at their one job. It will also help immensely when you need to "version" the system or introduce a different serializer (JSON, protobuf, etc).

Re your bullets:

  • I suspect any concrete list type (even your own) with Add etc will work
  • I don't recommend that to anyone - it is painful to do reliably
  • nothing ugly about attributes; again, I suspect your complaint is about attributing your domain model - so: fine, don't do that - have a separate model; you can actually do all this at runtime, but it is much more work (see XmlAttributeOverrides, but watch out for leaking assemblies if you do this)
  • don't underestimate how much work that is; the basics - seductively easy; but the non-trivial scenarios can be brutal

Upvotes: 7

sergiogarciadev
sergiogarciadev

Reputation: 2202

For use interface or derivade classes you MUST use the XmlSerializer(Type type, Type[] extraTypes) constructor.

In extraTypes you MUST include all possible classes which can implement the interfaces in your classes.

Upvotes: 0

Related Questions