Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Languages / C#

Using WCF Data Contract Known Types by Example

5.00/5 (1 vote)
4 Mar 2014CPOL2 min read 29.1K  
Using WCF Data Contract known types by example

Introduction

Data Contract describes the type of data that will be sent or received between a service and a client. But in certain scenarios, sent or received data is not known between the communicating parties. For example, a service sending data back to client is not the actual data contract but a derived type of it. In such cases, there will be a de-serialization problem. De-serialization engine will not recognize the derived Data Contract type and will generate an error.

In order to handle such scenarios, Data Contract Known types are available in Windows Communication Foundation. So by definition, "Known Type in WCF is an acceptable derived type for a Data Contract".

In one of my previous WCF Service articles, I explained WCF KnowTypeAttribute with the help of a simple example. But here in this WCF Tutorial, I'll try to discuss all possible ways to use Data Contract Known Types, so that the reader can get a detailed understanding about Known Types and be able to use it in various practical scenarios.

Consider we have a service contract "IVehicleService" as:

C#
[ServiceContract]
public Interface IVehicleService
{
     [OperationContract]
     Vehicle AddNewVehicle(Vehicle myVehicle);

     [OperationContract]
     bool UpdateVehicle(Vehicle myVehicle);  
}

We can use Data Contract Known Types at different levels depending upon the requirements:

  • Global Level
    • Using Code at base type
    • Using Web.config
  • Service Contract Level
  • Operation Contract Level

Using Globally (Using Code at base type)

In order to use globally, we can apply KnownTypeAttribute at base Data Contract type as used in the following example:

C#
[KnownType(typeof(Car))]
[KnownType(typeof(Truck))]
[DataContract]
public class Vehicle 
{
}

[DataContract]
public class Car : Vehicle
{
}

[DataContract]
public class Truck : Vehicle
{
}

In the above example, you can see that KnownTypeAttribute is used at base Data Contract Type, i.e., Vehicle. So, now these derived types are globally known for all service and operation contracts wherever the Vehicle type is used.

Using Globally (Using Web.config)

We can achieve the same as above using web.config as follows:

XML
<system.runtime.serialization>
     <dataContractSerializer>
                  <declaredTypes>
                             <add type="MyService.Vehicle, 
                                                MyService, Version=<version here>, 
                                                Culture=Neutral, PublicKeyToken=null">
                                         <knownType type="MyService.Car, 
                                                MyService, Version=<version here>, 
                                                Culture=Neutral, PublicKeyToken=null" />
                                         <knownType type="MyService.Truck, 
                                                MyService, Version=<version here>, 
                                                Culture=Neutral, PublicKeyToken=null" />
                            </add>
                  </declaredTypes>
     </dataContractSerializer>
</system.runtime.serialization>

The above configuration will also make the derived types (Car, Truck) as globally known Types.

Using at Service Contract

For certain scenarios, if we wanted to make such derived types as known types for a particular service, we can apply ServiceKnownTypeAttribute as follows:

C#
[ServiceKnownType(typeof(Car))]
[ServiceKnownType(typeof(Truck))]

[ServiceContract]
public Interface IVehicleService
{
     [OperationContract]
     Vehicle AddNewVehicle(Vehicle myVehicle);

     [OperationContract]
     bool UpdateVehicle(Vehicle myVehicle);  
}

Now, these derived types are known to all operation contracts within IVehicleService.

Using at Operation Contract

In order to make it more restricted, i.e., for only a specific operation contract within a service, we can do the following:

C#
[ServiceContract]

public Interface IVehicleService
{
      [ServiceKnownType(typeof(Car))]
      [ServiceKnownType(typeof(Truck))]
      [OperationContract]
      Vehicle AddNewVehicle(Vehicle myVehicle);

      [OperationContract]
      bool UpdateVehicle(Vehicle myVehicle);  
}

So now, these derived types are known types only for AddNewVehicle method and not for the UpdateVehicle or other operations within IVehicleService.

This Service tutorial provides all possible ways for associating Data Contract Known Types in WCF.

The reader of this article might also be interested in:

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)