KnownType Attribute in WCF

Introduction
 
KnownType Attribute
 
Create a WCF application and implement the service contract and data contract as follows.
  1.  [ServiceContract]  
  2. public interface IsaveItem  
  3. {  
  4.    [OperationContract]  
  5.    void Save(Item value); //Contract expects passed data to be of type Item.  
  6. }  
  1.    [DataContract]    
  2.    public class Item    
  3.    {    
  4.        [DataMember]    
  5.        public int id { getset; }    
  6.        [DataMember]    
  7.        public String Name { getset; }    
  8.        [DataMember]    
  9.        public double price { getset; }    
  10.    }    
  11.    [DataContract]    
  12.    //you can see that PenItem inherits from Item.  
  13.    public class PenItem:Item    
  14.    {    
  15.        public PenItem()    
  16.        {    
  17.            Name = "Pen Item";    
  18.        }    
  19.    }  
  20. public class SavePenItem : IsaveItem  
  21. {  
  22.    public void Save(Item value)  
  23.    {  
  24.    Console.WriteLine("Received Data From Client{0},{1}", value.Name,value.price);  
  25.    }  
  26. }     
Let's try to run and test the service (I have created a WCF Service library from Visual Studio to test it). The expected data contract to the service is of type Item. Now let's try to pass a type of PenItem (derived class from Item) to the service. We would get an error as in the following:
 
 
 
The deserializing engine expects the type to be Item and not the PenItem. That is where the KnownType Attribute is relevant, letting the engine to know that the contract could also be of type PenItem. You can let the deserializing engine know about the types in one of three ways. They are as follows:
  • Using the attribute with DataContract.
  1. [DataContract]  
  2. [KnownType(typeof(PenItem))]  
  3.  public class Item  
  4.  {  
  5.      [DataMember]  
  6.      public int id { getset; }  
  7.      [DataMember]  
  8.      public String Name { getset; }  
  9.      [DataMember]  
  10.      public double price { getset; }  
  11.  }  
  • ServiceKnownTypeAttribute: Defining the known type with Service Contract
  1. [ServiceContract]  
  2.  [ServiceKnownType(typeof (PenItem)) ]   
  3. //Defining known type at service level  
  4.     public interface IsaveItem  
  5.     {  
  6.         [OperationContract]  
  7.         void Save(Item value);  
  8.     }  
  • Declarative Known Types: Defining the known type at the configuration level.
  1. <configuration>  
  2. <system.runtime.serialization>  
  3. <dataContractSerializer>  
  4. <declaredTypes>  
  5. <add type="Knowntype.Item,Knowntype, Version=1.0.0.0, Culture=neutral,PublickeyToken=null">  
  6. <knownType type="knowntype.PenItem,knowntype, Version=1.0.0.0, Culture=neutral,PublicKeyToken=null"/>  
  7. </add>  
  8. </declaredTypes>  
  9. </dataContractSerializer>  
  10. </system.runtime.serialization>  
  11. </configuration>