Sometimes you get requirements that really push you to do things the way they’re not supposed to be done.
In a recent project we had to do quite complex operations on the client (WPF) and send complex objects (all operations as one transaction) back to the server, but still the communication to the server had to be done using WCF. This forced us to send objects over the wire that could not be serialized by the default WCF serializer.
Fortunately there is a way to specify which serializer WCF should use. If you create a new attribute:
public class NetDataContractAttribute : Attribute, IOperationBehavior { public void AddBindingParameters (OperationDescription description, BindingParameterCollection parameters) { } public void ApplyClientBehavior (OperationDescription description, ClientOperation proxy) { ReplaceDataContractSerializerOperationBehavior(description); } public void ApplyDispatchBehavior (OperationDescription description, DispatchOperation dispatch) { ReplaceDataContractSerializerOperationBehavior(description); } public void Validate(OperationDescription description) { } private static void ReplaceDataContractSerializerOperationBehavior (OperationDescription description) { DataContractSerializerOperationBehavior behavior = description.Behaviors .Find<DataContractSerializerOperationBehavior>(); if (behavior != null) { description.Behaviors.Remove(behavior); description.Behaviors .Add(new NetDataContractSerializerOperationBehavior (description)); } } public class NetDataContractSerializerOperationBehavior : DataContractSerializerOperationBehavior { public NetDataContractSerializerOperationBehavior (OperationDescription operationDescription) : base(operationDescription) { } public override XmlObjectSerializer CreateSerializer (Type type, string name, string ns, IList<Type> knownTypes) { return new NetDataContractSerializer(); } public override XmlObjectSerializer CreateSerializer (Type type, XmlDictionaryString name, XmlDictionaryString ns, IList<Type> knownTypes) { return new NetDataContractSerializer(); } } }
and decorate the methods on your interface with this attribute:
[OperationContract, NetDataContract]
the .NET serializer is used instead.
If the client is also .NET, this is no issue. It’s like Remoting with WCF.
It’s not really the way WCF is supposed to work (it should be open, usable by all kinds of clients). But if your requirements are ridiculous, and it’s a .NET-only solution, you can definitely do it like this. 🙂