WCF

WCF Examples

WCF

WCF Projects

WCF Project

adplus-dvertising
Data Contract Hierarchy
Previous Home Next

Data contract class canbe the subclass of another data contract class. Since the DataContractattribute is not inheritable so WCF requires that every level in the class hierarchy explicitly opt in for a given data contract.

[DataContract]
class Contact
{
   [DataMember]
   public string FtName;
   [DataMember]
   public string LName;
}
[DataContract]
class Customer : Contact
{
   [DataMember]
   public int CNumber;
}
  1. Known Types

    The KnownType attribute allows you to designate acceptable subclasses for the data contract:

    [DataContract]
    [KnownType(typeof(Customer))]
    class Contact
    {...}
    [DataContract]
    class Customer : Contact
    {...}
    

    The KnownType attribute includes the subclass in the metadata so that the client will have its own definition of the subclass and will be able to pass the subclass instead of the base class. Using the base class, all contracts and operations are affected by The KnownType attribute , across all services and endpoints on the host side and allowing it to accept subclasses instead of base classes.

    If the client also applies the KnownType attribute on its copy of the base class, it can in turn receive the known subclass back from the service.

  2. Service Known Types

    WCF also provides the ServiceKnownTypeAttribute, defined as:

    [AttributeUsage(AttributeTargets.Interface|
    AttributeTargets.Method|
    AttributeTargets.Class,
    AllowMultiple = true)]
    public sealed class ServiceKnownTypeAttribute : Attribute
    {
    public ServiceKnownTypeAttribute(Type type);
    //More members
    }
    

    Instead of using the KnownType attribute on the base data contract we can apply the ServiceKnownType attribute on a specific operation on the service side. Then, only that operation (across all supporting services) can accept the known subclass.

    [DataContract]
    class Contact
    {...}
    [DataContract]
    class Customer : Contact
    {...}
    [ServiceContract]
    interface IContactManager
    {
       [OperationContract]
       [ServiceKnownType(typeof(Customer))]
       void AddContact(Contact contact);
       [OperationContract]
       Contact[] GetContacts();
    }
    
  3. Multiple Known Types

    Tthe KnownType and the ServiceKnownType attributes both  can be applied multiple times to inform WCF about as many known types as required:

    [DataContract]
    class Contact
    {...}
    [DataContract]
    class Customer : Contact
    {...}
    [DataContract]
    class Person : Contact
    {...}
    [ServiceContract]
    [ServiceKnownType(typeof(Customer))]
    [ServiceKnownType(typeof(Person))]
    interface IContactManager
    {...}
    
  4. Configuring Known Types

    The main disadvantage of the known types attributes is that they require the service or the client to know in advance about all possible subclasses the other party may want to use. Adding a new subclass necessitates changing the code, recompiling, and redeploying. To alleviate this, WCF lets you configure the known types in the service's or client's config file.

    <system.runtime.serialization>
       <dataContractSerializer>
    <declaredTypes>
       <add type = "Contact,Host,Version=1.0.0.0,Culture=neutral,
      PublicKeyToken=null">
     <knownType type = "Customer,MyClassLibrary,Version=1.0.0.0,
      Culture=neutral,PublicKeyToken=null"/>
       </add>
    </declaredTypes>
       </dataContractSerializer>
    </system.runtime.serialization>
    
  5. Object and Interfaces

    The base type of a data contract class or a struct can be an interface:

    Interface IContact
    {
       string FirstName
       {get;set;}
       string LastName
       {get;set;}
    }
    [DataContract]
    class Contact : IContact
    {...}
    

    You can use such a base interface in your service contract or as a data member in a data contract if you use the ServiceKnownType attribute to designate the actual data type:

    [ServiceContract]
    [ServiceKnownType(typeof(Contact))]
    interface IContactManager
    {
       [OperationContract]
       void AddContact(IContact contact);
    
       [OperationContract]
       IContact[] GetContacts();
    }
    
Previous Home Next