Question

I'm trying to implement a custom error handling in WCF with IErrorHandler interface. I would like to translate unhandled exceptions to the custom fault, which structure I obtained in XSD.

My code looks like this:

public void ProvideFault(Exception error, MessageVersion version, ref Message fault)
{
    if (!(error is FaultException))
    {
        var customFault = new MyCustomFault
        {
            FaultString = "Something gone wrong",
            Detail = new DetailType
            {
                GeneralFault = new GeneralFaultType
                {
                    Errors = new[]
                    {
                        new ErrorType
                        {
                                Code = "333"
                        }
                    }
                }
            }
        };

        var faultException = new FaultException<MyCustomFault>(customFault);
        var msgFault = faultException.CreateMessageFault();
        fault = Message.CreateMessage(version, msgFault, faultException.Action);
    }
}

But this code produces output soap message

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
   <s:Body>
      <s:Fault>
         <faultcode>s:Client</faultcode>
         <faultstring xml:lang="cs-CZ">The creator of this fault did not specify a Reason.</faultstring>
         <detail>
... MyCustomFault goes here...
         </detail>
      </s:Fault>
   </s:Body>
</s:Envelope>

I'm able to influence only detail element of the fault. I would like to achieve, that instead of Fault element from namespece "http://schemas.xmlsoap.org/soap/envelope/" would be my custom fault object. Is that even possible? I'm using XmlSerializer.

Thank you, Michal

Was it helpful?

Solution

No, unfortunately , it's not possible. The only way for WCF service to inform client about error it through soap fault message. Thus WCF service must follow soap specification.

Following specification all fault messages must have the same structure. See specification: SOAP 1.2, find section 5.4.6 SOAP Fault Codes. You can find and example (almost the same as you have provided) there and description of all the nodes.

In SOAP 1.2 was introduced Detail node (please refer to the specification: Section 5.4.5 SOAP Detail Element).

Providing your fault contract you can inject your custom error in xml form here (inside Detail element). But other xml structure is unchangeable.

OTHER TIPS

If you need to follow a vendor's specification, you have the option of defining an xml serialization and then generate an xmlReader, then pass that reader into a message. I did something similar so I could unit test a behavior/messageInspector that fixed faults coming in.

var xtr = new XmlTextReader("CustomSoapFault.xml");

// I'm only allocating 1MB, you could allocate more if needed
var message = Message.CreateMessage(xtr, 1024 * 1024, MessageVersion.Soap11);

Where the contents of CustomSoapFault.xml are

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
   <s:Body>
      <s:Fault>
          ... CustomFault goes here...
      </s:Fault>
   </s:Body>
</s:Envelope>

When .NET generates a message with this, the Message.IsFault property will return true.

Also, make sure to update the soap's namespace and the MessageVersion so they match.

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