I have a class Team that holds a generic list:
[DataContract(Name = "TeamDTO", IsReference = true)]
public class Team
{
[DataMember]
private IList<Person> members = new List<Person>();
public Team()
{
Init();
}
private void Init()
{
members = new List<Person>();
}
[System.Runtime.Serialization.OnDeserializing]
protected void OnDeserializing(StreamingContext ctx)
{
Log("OnDeserializing of Team called");
Init();
if (members != null) Log(members.ToString());
}
[System.Runtime.Serialization.OnSerializing]
private void OnSerializing(StreamingContext ctx)
{
Log("OnSerializing of Team called");
if (members != null) Log(members.ToString());
}
[System.Runtime.Serialization.OnDeserialized]
protected void OnDeserialized(StreamingContext ctx)
{
Log("OnDeserialized of Team called");
if (members != null) Log(members.ToString());
}
[System.Runtime.Serialization.OnSerialized]
private void OnSerialized(StreamingContext ctx)
{
Log("OnSerialized of Team called");
Log(members.ToString());
}
When I use this class in a WCF service, I get following log output
OnSerializing of Team called
System.Collections.Generic.List 1[XXX.Person]
OnSerialized of Team called
System.Collections.Generic.List 1[XXX.Person]
OnDeserializing of Team called
System.Collections.Generic.List 1[XXX.Person]
OnDeserialized of Team called
XXX.Person[]
After the deserialization members is an Array and no longer a generic list although the field type is IList<> (?!)
When I try to send this object back over the WCF service I get the log output
OnSerializing of Team called
XXX.Person[]
After this my unit test crashes with a System.ExecutionEngineException, which means the WCF service is not able to serialize the array. (maybe because it expected a IList<>)
So, my question is: Does anybody know why the type of my IList<> is an array after deserializing and why I can’t serialize my Team object any longer after that?
Thanks
You’ve run into one of the
DataContractSerializergotchas.Fix: Change your private member declaration to:
OR change the property to:
And it will work. The Microsoft Connect bug is here
This problem occurs when you deserialize an object with an
IList<T>DataMember and then try to serialize the same instance again.If you want to see something cool:
It will print
int[] is IList<int>: True.I suspect this is possibly the reason you see it come back as an array after deserialization, but it is quite non-intuitive.
If you call the Add() method on the
IList<int>of the array though, it throwsNotSupportedException.One of those .NET quirks.