Building a Data Contract Serializer Behavior

In configuration there's a DataContractSerializer behavior that I can add to my service, but the class it uses is internal. How do I get the same behavior programmatically?

The DataContractSerializer behavior is a shortcut for setting the MaxItemsInObjectGraph and IgnoreExtensionDataObject options on endpoints. You can get a similar effect by looping over the operations in your service.

First, if the DataContractSerializer behavior is supplied as a service behavior, it applies to all of the non-metadata endpoints in your service. To check whether an endpoint is a metadata endpoint, we look for the following things:

The endpoint has a ServiceMetadataBehavior in its description
The endpoint service type is IMetadataExchange
The endpoint contract name is IMetadataExchange in the namespace

Assuming that we've found a non-metadata endpoint, or the DataContractSerializer behavior is supplied as an endpoint behavior instead of a service behavior, we now scan through all of the operation descriptions on the endpoint contract. For each operation description we scan through all of its behaviors to find a DataContractSerializerOperationBehavior. The operation behavior is what stores the settings for the operation.

Finally, if the settings on the DataContractSerializerOperationBehavior were not already explicitly set, we change them to the values from the DataContractSerializer behavior. By doing this check, you can apply the behavior to an endpoint without overriding any values you set manually. This is the only step that you can't duplicate as the flag to tell where the value came from is internal. If you explicitly set the MaxItemsInObjectGraph or IgnoreExtensionDataObject options on an operation, then you'll need to explicitly exclude those operations in the behavior you write as well.