2011/02/04

WCF Serialization: Dynamically add derived types to web service ServiceKnownType attribute

It is a known issue that you need to add the list of derived types of your base class in order for the WCF serializer to recognize them.

Suppose you have a class hierarchy like the following:

public abstract class MyBaseClass
{
[DataMember]

public int id { getset; }

}

public class DerivedType : MyBaseClass
{
[DataMember]
public string Name { getset; }

}

Now in your WCF service definition, your code should like this:

[ServiceContract]
interface MyService
{
[OperationContract]
[ServiceKnownType(typeof(DerivedType)]
void HelloWorld(MyBaseClass param1);

}

This obviously creates a problem that anytime you add a new derived type; you need to add it to the ServiceKnownType attribute so that the WCF serializer recognizes the new types.

To solve this problem and allow the newly created derived types to be dynamically serialized without the need to modify the service definition code, you need to do the following:

Create a method that returns a list of the derived types as follows:

public static class TypesHelper
{
public static IEnumerable GetKnownTypes(ICustomAttributeProvider provider)
{

Assembly assembly = Assembly.GetAssembly(typeof(MyBaseClass));
List<Type> types = assembly.GetExportedTypes().Where(e => e.BaseType != null && e.BaseType.BaseType == typeof(MyBaseClass)).ToList();

return types;

}

}

Now add a call to the above created method in the ServiceKnownType attribute as follows:

[OperationContract]
[ServiceKnownType("GetKnownTypes", typeof(TypesHelper))]
void HelloWorld(MyBaseClass param1);

This way, we are benefiting from the ability to use our own method that dynamically supplies the derived types to the WCF serializer.