This attribute is used to include additional classes in the metadata of the service so that clients could see them. Let's take for example the following:
[DataContract]
public class BaseModel
{
[DataMember]
public string Id { get; set; }
}
[DataContract]
public class ChildModel: BaseModel
{
[DataMember]
public string Foo { get; set; }
}
and the following service contract:
[ServiceContract]
public interface IMyService
{
[OperationContract]
BaseModel Get();
}
and that you implement it like this:
public class MyService: IMyService
{
public BaseModel Get()
{
return new ChildModel();
}
}
Now when WCF exposes the metadata of this service it looks at the service contract and the operations being involved so it discovers the Get operation which returns the BaseModel type. So the BaseModel class is automatically exposed in the metadata. The problem is that when you try to invoke the service the actual implementation returns a ChildModel
for WCF has no knowledge. The clients of the service neither have knowledge of this type.
So you need to explicitly indicate indicate this class that you are using in the implementation but is not part of the contract. This could be done by using the KnownType attribute:
[DataContract]
[KnownType(typeof(ChildModel))]
public class BaseModel
{
[DataMember]
public string Id { get; set; }
}
Another way to specify this known type is to do it by using the config file:
<system.runtime.serialization>
<dataContractSerializer>
<declaredTypes>
<add type="MyCompany.BaseModel, MyAssembly, Version=1.0.0.0, Culture=neutral, PublicKeyToken=XXXXXX, processorArchitecture=MSIL">
<knownType type="MyCompany.ChildModel, MyAssembly, Version=1.0.0.0, Culture=neutral, PublicKeyToken=XXXXXX, processorArchitecture=MSIL"/>
</add>
</declaredTypes>
</dataContractSerializer>
</system.runtime.serialization>