Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

XmlSerializer won't serialize IEnumerable

I have an invocation logger that is intended to record all method calls along with the parameters associated with the method using XmlSerializer. It works well for most of the calls, but it throws an exception for all methods that has a parameter of IEnumerable type.

For example, void MethodWithPlace( Place value ) would be serialized, but void MethodWithPlace( IEnumerable<Place> value ) would not.

The exception is

System.NotSupportedException: Cannot serialize interface System.Collections.Generic.IEnumerable`1[[Place, Test, Version=0.0.0.0, Culture=neutral]].

What should I do to make it work with those methods with IEnumerable as one of its parameters?

like image 405
uni Avatar asked Feb 01 '12 19:02

uni


People also ask

Can IEnumerable be serialized?

Some of these types implement IEnumerable. For these types, only the enumeration is serialized. All other class members are not serialized.

Is XmlSerializer thread safe?

Since XmlSerializer is one of the few thread safe classes in the framework you really only need a single instance of each serializer even in a multithreaded application. The only thing left for you to do, is to devise a way to always retrieve the same instance.


2 Answers

The way you serialize an IEnumerable property is with a surrogate property

[XmlRoot] public class Entity {    [XmlIgnore]    public IEnumerable<Foo> Foo { get; set; }     [XmlElement, Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]    public List<Foo> FooSurrogate { get { return Foo.ToList(); } set { Foo = value; } } } 

It's ugly, but it gets the job done. The nicer solution is to write a surrogate class (i.e. EntitySurrogate).

like image 162
Herman Schoenfeld Avatar answered Oct 08 '22 02:10

Herman Schoenfeld


Basically an XmlSerializer can't serialize an interface. The solution, then, is to give it a concrete instance to serialize. Depending on how your invocation logger works, I would consider using

var serializer = new XmlSerializer(value.GetType()); 
like image 30
Kyle W Avatar answered Oct 08 '22 01:10

Kyle W