Over the past couple of weeks I’ve been doing some WCF development and have been using WCF KnownTypes and ServiceKnownTypes to support inheritance and the use of interfaces when creating web services.

Using the KnownType and ServiceKnownTypes attribute you can have a operation contract with a signature that either returns or accepts a base class such as the one below:

   1: [ServiceContract]
   2: public interface IService1
   3: {
   4:     [OperationContract]
   5:     IPerson GetPerson();
   6: }

This allows the web service to pass back any sub class that inherits from the IPerson interface, such as a person class or even an employee class that inherits from person.

This can be done using the KnownType attribute on the sub class associating the interface with the concrete implementation. The sub class adds the attribute [KnownType(typeof(baseclass)] passing in the generalised object or interface.

   1: public interface IPerson
   2: {
   3:     string FirstName { get; set; }
   4:  
   5:     string LastName { get; set; }
   6: }
   7:  
   8: [DataContract(Name = "Person")]
   9: [KnownType(typeof(IPerson))]
  10: public class Person : IPerson
  11: {
  12:  
  13:     #region IPerson Members
  14:     [DataMember(Name = "FirstName")]
  15:     public string FirstName { get; set; }
  16:  
  17:     [DataMember(Name = "LastName")]
  18:     public string LastName { get; set; }
  19:     #endregion
  20: }

This will now allow the web service to pass back the Person sub class where the interface IPerson is used in the operation contract. However, I prefer using the ServiceKnownType attribute on the method signature, rather than using the KnownType attribute on the whole class.

   1: [OperationContract]
   2: [ServiceKnownType(typeof(Person))]
   3: IPerson GetPerson();

ServiceKnownTypes can also be used to a number of different classes inheriting from a single base class by adding multiple attributes to the method.

   1: [OperationContract]
   2: [ServiceKnownType(typeof(Person))]
   3: [ServiceKnownType(typeof(Employee))]
   4: IPerson GetPerson();

The web method can now pass back either the Person or Employee object from the service.

Enjoy… :)