DataContract and KnownTypes for Inherited classes using Service Bus 1.0

296 Views Asked by At

Hi I have the following class hierarchy:

public class SuperJob{
}

public class JobA:SuperJob{
}

public class JobB:SuperJob{
}

When i try to deserialise a SuperJob i get

Expecting element 'SuperJob' from namespace 'http://schemas.datacontract.org/2004/07/...'.. Encountered 'Element'  with name 'JobA', namespace 'http://schemas.datacontract.org/2004/07/...'.

I have annotated my classes as follows:

[DataContract]
[KnownType(typeof(JobA))]
[KnownType(typeof(JobB))]
public class SuperJob{
}

[DataContract]
public class JobA:SuperJob{
}

[DataContract]
public class JobB:SuperJob{
}

Not sure what i am doing wrong? Any ideas how do i fix this?

2

There are 2 best solutions below

0
user1950055 On BEST ANSWER

Managed to fix this issue, there is a bug in the way the service bus instantiates the serialiser. looks like internally it instantiates the serialiser with JobA.getType(). So the best way forward is to create your own DataSerializer object which uses typeOf(JobA) and pass that in both when sending the message on to the bus and reading off the bus.

0
Ajay Kelkar On

Use [ServiceKnownType] attribute on your service :

[ServiceKnownType(typeof(JobA))]
[ServiceKnownType(typeof(JobB))]
public interface IJobService 
{
.... methods
}

Another approach would be to pass knowntypes in DataContractSerializer constructor.

List<Type> knownTypeList = new List<Type>();
knownTypeList.Add(typeof(JobA));
knownTypeList.Add(typeof(JobB));

// Create a DatatContractSerializer with the collection.
DataContractSerializer ser2 = new DataContractSerializer(
                                  typeof(SuperJob), knownTypeList);