views:

829

answers:

3

One of my [DataContract] classes contains a [DataMember] which is a List. BaseClass has a few different sub-classes.

Whenever that List contains instances of any sub-class, an exception occurs during/after the Service is returning to the request channel. If the List does not contain any sub-classes, it works fine.

Here is an example of my code (which itself doesn't work):

public class BaseClass
{
}
public class BaseClassSub : BaseClass
{
}

[DataContract]
public class MyClass
{
 List<BaseClass> m_Classes = new List<BaseClass>();

 [DataMember]
 public List<BaseClass> Classes
 {
  get { return m_Classes; }
  set { m_Classes = value; }
 }
}


[ServiceContract]
public interface IMyService
{
 [OperationContract]
 MyClass GetMyClass(); 

}

public class MyService : IMyService
{
 public MyClass GetMyClass()
 {
  MyClass o = new MyClass();

  //THIS WORKS!!!!
  //o.Classes = new List<BaseClass>() { new BaseClass() };

  //THIS DOES NOT WORK!!!!
  o.Classes = new List<BaseClass>() { new BaseClassSub() };

  return o;
 }
}

I get the following error when debugging:

The socket connection was aborted. This could be caused by an error processing your message or a receive timeout being exceeded by the remote host, or an underlying network resource issue. Local socket timeout was '00:00:59.6560000'.

Anyone know how to resolve this issue (getting it to handle sub-classes)?

+2  A: 

You need to tell the Data Contract Serializer the types it might encounter. See Data Contract Known Types.

John Saunders
Thanks! I just missed your reply as I was posting!
A: 

After more searching, I went ahead and put a [KnownType] attribute on BaseClass (see below), and it is now working.

[KnownType(typeof(BaseClassSub))]
public class BaseClass
{
}

I hope this helps others at least!

A: 

DataContrat deserialization does not call constructor and initial values for the members are not assigned

It means that m_Classes will be null after deserializing. Make sure you cover this in your code by either OnDeserialize event or by creating list in getter.

Maxim Alexeyev