Share via


Using base types in WCF

I was recently asked if it's possible to expose a base type (maybe an abstract class or interface) as a parameter in a WCF operation and allow different types to be specified when invoked. Unsurprisingly, the WCF guys thought of this and included some attributes to help.

Let's imagine we have an interface IEntity and two derived types MyEntity1 and MyEntity2. We need to tell WCF about the two derived types if we'd like them added to the Service' metadata and we can do this using the ServiceKnownType attribute:

[OperationContract]
[ServiceKnownType(typeof(MyEntity1))]
[ServiceKnownType(typeof(MyEntity2))]
void Save(IEntity entity);

Sadly, the proxy that's generated when you expose an interface exposes a parameter of type 'object' and not IEntity - which doesn't exactly create the best looking API. However, if we use an actual class then the proxy exhibits the appropriate parameter type. Better still, we can apply the KnownType attribute to the superclass and WCF will spot this wherever that type is exposed as a parameter.

[DataContract]
[KnownType(typeof(MyEntity1))]
[KnownType(typeof(MyEntity2))]
public abstract class BaseEntity
{

Sadly you can't apply the KnownType attribute to interfaces but you can still use the ServiceKnownType attribute on either the OperationContract method or the ServiceContract interface/class. Just not on the type itself.

Naturally, I wondered if it was possible to create a new type, on the client, that inherited from the proxy generated BaseEntity and send that across the wire. I was particularly curious to see how it would have been serialised if this was indeed possible. Unsurprisingly, in my experiments at least, this threw a nasty CommunicationException: "There was an error while trying to serialize parameter https://tempuri.org/:baseEntity". Hohum.

Originally posted by Josh Twist on 18th of March 2009 here.