Question

I'm using a custom XmlObjectSerializer in my application. To do so, I replace XmlSerializerOperationBehavior with MyOperationBehavior which looks something like this:

public class MyOperationBehavior : DataContractSerializerOperationBehavior
{
    public override XmlObjectSerializer CreateSerializer(Type type, string name, string ns, IList<Type> knownTypes)
    {
        return new MySerializer();
    }

    public override XmlObjectSerializer CreateSerializer(Type type, XmlDictionaryString name, XmlDictionaryString ns, IList<Type> knownTypes)
    {
        return new MySerializer();
    }
}

The problem is that by doing so, any faults are deserialized to the non-generic FaultException rather than FaultException<TDetail> and I'm unable to access the fault's details.

After doing some investigating I found that the root of the problem is the fact that by inheriting from DataContractSerializerOperationBehavior, .NET internally sets the FaultFormatter to DataContractSerializerFaultFormatter which doesn't know how to deserialize the fault's detail (rather than XmlSerializerFaultFormatter). The problem is definitely not in MySerializer, since the FaultException is thrown before it gets to my ReadObject method.

So my question is what can I do to make WCF deserialize my fault details correctly? I tried looking for a way to set the FaultFormatter myself, but had no luck, especially because all these formatters are internal.

Was it helpful?

Solution

I've found a way to get the FaultExceptions to deserialize properly. It's very hackish though and I feel a bit uncomfortable using it, but I thought I'd share in case anyone else is looking to solve this issue. If a better answer is available I'd be happy to hear.

In order to replace the serializer with my own custom serializer what I done is replace the XmlSerializerOperationBehavior with my own MyOperationBehavior (the way it's done everywhere I saw on the web). I found though that if instead of replacing the behavior I just add my new behavior to the list of behaviors, the faults will be deserialized as expected. One thing to note though is that MyOperationBehavior should be placed in the list of behaviors before XmlSerializerOperationBehavior - otherwise the custom serializer won't be used.

description.Behaviors.Insert(0, new MyOperationBehavior());

As I said, having these two behaviors together sounds like it can cause problems I'm not aware of, so I'd be happy to get input on that as well if you know of any conflicts that this solution may raise.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top