Before the Feb bits, WCF came with one new serializer called DataContractSerializer (DCS). However, DCS came with two modes: SharedContract and SharedType. The modes reflected whether you were planning to share the schema contract across the wire or the .NET type information respectively.
In general, sharing the schema contract is the preferred and recommended approach because it loosens the coupling across the wire by conforming to the SO tenet "share schema and contract, not implementation". Nevertheless, WCF still wants to support .NET remoting-style applications where maintaining type fidelity across the wire is important...hence, the SharedType mode. With SharedType, the .NET type information is serialized into each message so the same type can be used on the other side.
As of the Feb CTP, the WCF team decided to split these two modes into separate classes - so now you have DataContractSerializer (SharedContract) and NetDataContractSerializer (SharedType). The WCF folks want to encourage folks to use the "shared contract" model as much as possible so the DCS is the default serializer throughout the framework -- contracts always use DCS unless overriden with a serializer format attribute.
For example, if you'd prefer to use XmlSerializer instead of DCS, you can annotate the interface or individual methods with [XmlSerializerFormat]. However, because the WCF team is trying to discourage the use of NDCS, there is no such attribute for enabling it, which is probably a good thing. If you wish to use NDCS with your contracts, you'll have to write a custom behavior to inject it at the right time. Here's an example:
public class NetDataContractFormat : 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 dcsOperationBehavior =
description.Behaviors.Find<
DataContractSerializerOperationBehavior>();
if (dcsOperationBehavior != null)
{
description.Behaviors.Remove(dcsOperationBehavior);
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();
}
}
}
This solution basically overrides the behavior of the built-in DataContractSerializerOperationBehavior, which is called by the runtime to create the serializer when needed (see CreateSerializer).
You can grab the complete source file from
here.
Posted
Apr 21 2006, 12:42 PM
by
Aaron Skonnard