Let's have a very simplified example:
[ServiceContract]
public interface IMyService
{
[OperationContract]
T1 GetData();
}
[DataContract]
[KnownType(typeof(T2))]
public class T1
{
[DataMember]
int Value { get; set; }
}
[DataContract]
public class T2: T1
{ }
I need to be able to send T1, but receive it as T2 on client side (simplified reasons: fast conversion of business objects to client readonly types; convert server pooled objects to client unpooled types. I can elaborate further if needed).
To make it little more complicated - type tree for the data being sent has more types, e.g.:
[OperationContract]
TBase GetData();
[DataContract]
[KnownType(typeof(T1))]
[KnownType(typeof(T2))]
[KnownType(typeof(T3))]
[KnownType(typeof(Tn))]
public class TBase
{
[DataMember]
int Value { get; set; }
}
[DataContract]
public class T1: TBase { }
[DataContract]
public class T2: TBase { }
[DataContract]
public class T3: TBase { }
[DataContract]
public class Tn: TBase { }
And I need to receive all types as is, with exception of T1, that needs to be received as T2.
I tested that serialization/deserialization part is easily doable with DataContractSerializer, but I cannot find out how to instruct WCF to use different DataContractSerializer to deserialize T1.
Edit1: It looks like this should be doable byderiving custom DataContractResolver and injecting this to Operations contracts on both (client-server) WCF sides. I got this almost working - serialization-deserialization itself works as expected, WCF still fails. I'll try to post answer once I find out the reason
Two WCF extensibility points that come to mind:
DataContractResolver
(as mentioned in your own answer) - lets you define a new matching between XML and its desired .Net type. Read more here.IDataContractSurrogate
- substitutes one .Net type with another for serialization purposes. No XML is involved. Read more here.They are both injected in a similar way, via properties on the DataContractSerializerOperationBehavior
.