There's a new WCF feature in the .NET Framework 3.5 SP1 release that I just recently learned about. It has to do with serialization of SOAP faults when using the XmlSerializer for your service rather than the default DataContractSerializer.
Consider this scenario: You have elected to use the XmlSerializer for your service because of some rather complicated schema that the DataContractSerializer doesn't support. You also have some rather complicated schema used to define fault contracts in your service. Prior to SP1, WCF would serialize any faults you returned from your service using the DataContractSerializer rather than the XmlSerializer even though you applied the XmlSerializerFormatAttribute to your service, potentially breaking the serialization between your service and client(s).
In SP1, support for XmlSerializer Faults was added via the SupportFaults property. There is a link to a sample in the XmlSerializer Faults document. Unfortunately, at the time of this writing that sample does not appear to exist - I've searched! So, I'm going to expand on the topic here.
SupportFaults is a boolean property that simply says this:
- If true, then WCF will use the XmlSerializer to serialize the fault.
- If false, then WCF will use the DataContractSerializer to serialize the fault. This is the default.
As an example, consider the following service definition:
Our service is using the XmlSerializer because of the XmlSerializerFormat attribute that is present.
Our fault contract returns a typed SOAP fault, UnknownStockFault, to the client in the event that an unknown ticker symbol is passed in. In this definition are some XML serialization attributes (XmlAttribute and XmlIgnore) that the XmlSerializer understands.
When your service returns this fault, it will be serialized by the DataContractSerializer (not the XmlSerializr) like this:
When in fact, you were probably expecting this:
Notice that "Symbol" is an attribute of the <UnknownStockFault> element and that the "ErrorCode" is missing.
So, how do you achieve the latter? By using the new SupportFaults property. For example: