Partager via


Replacing the Serializer, Part 1

A natural progression from yesterday's article about creating a new serializer is to put that serializer into the message processing pipeline. There have been several people that have already described how to do this. It's evidently not too uncommon. First though, I want to correct some recurring issues I've seen with these demonstrations.

The earliest writing that talks about the current model for replacing the serializer is by Sowmy. At least, that's the earliest writing that I know about. I'm pretty sure that Sowmy is just writing some really quick sample code here to illustrate the point. However, I've seen that same code copied elsewhere, such as Ingo Rammer's MSDN article on migrating to WCF. If you look at the snippet of code, you may notice a few issues.

 public override XmlObjectSerializer CreateSerializer(Type type, string name, string ns, IList<Type> knownTypes)
{
   return CreateDataContractSerializer(type, name, ns, knownTypes);
}

private static XmlObjectSerializer CreateDataContractSerializer(Type type, string name, string ns, IList<Type> knownTypes)
{
   return CreateDataContractSerializer(type, name, ns, knownTypes);
}

public override XmlObjectSerializer CreateSerializer(Type type, XmlDictionaryString name, XmlDictionaryString ns, IList<Type> knownTypes)
{
   return new DataContractSerializer(type, name, ns, knownTypes,
      0x7FFF /*maxItemsInObjectGraph*/,
      false/*ignoreExtensionDataObject*/,
      true/*preserveObjectReferences*/,
      null/*dataContractSurrogate*/);
}

The first issue is that the overload taking string parameters isn't going to work. It just calls itself in an infinite loop. The second issue is that creation of the DataContractSerializer has substituted defaults for many of the parameters rather than passing through the settings of the behavior. The code should look more like this:

 public override XmlObjectSerializer CreateSerializer(Type type, string name, string ns, IList<Type> knownTypes)
{
   return new DataContractSerializer(type, name, ns, knownTypes, this.MaxItemsInObjectGraph, this.IgnoreExtensionDataObject, true, this.DataContractSurrogate);
}

public override XmlObjectSerializer CreateSerializer(Type type, XmlDictionaryString name, XmlDictionaryString ns, IList<Type> knownTypes)
{
   return new DataContractSerializer(type, name, ns, knownTypes, this.MaxItemsInObjectGraph, this.IgnoreExtensionDataObject, true, this.DataContractSurrogate);
}

Next time: Replacing the Serializer, Part 2

Comments