Search code examples
c#wcfserializationdatacontractserializer

Instruct WCF to deserialize type T1 as T2


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


Solution

  • Two WCF extensibility points that come to mind:

    • Deriving from DataContractResolver (as mentioned in your own answer) - lets you define a new matching between XML and its desired .Net type. Read more here.
    • Implementing 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.