Retrieving Details from WCF FaultException Response

I successfully work with a third-party soap service. I added a service link to a soapy web service that automatically generated classes.

If an error occurs, the soap response is returned as follows:

<SOAP-ENV:Envelope xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"> <SOAP-ENV:Body> <SOAP-ENV:Fault> <faultcode>SOAP-ENV:Client</faultcode> <faultstring xsi:type="xsd:string">Error while reading parameters of method 'Demo'</faultstring> <detail xsi:type="xsd:string">Invalid login or password. Connection denied.</detail> </SOAP-ENV:Fault> </SOAP-ENV:Body> </SOAP-ENV:Envelope> 

I can catch the error, but not extract the item. I tried the following code:

 catch (FaultException ex) { MessageFault msgFault = ex.CreateMessageFault(); var elm = msgFault.GetDetail<string>(); //throw Detail } 

However, these are Errors with the following as a detail node is not an object:

 Expecting element 'string' from namespace 'http://schemas.datacontract.org/2004/07/MyDemoNamespace'.. Encountered 'Text' with name '', namespace ''. 

This is a third-party API, so I cannot change the answer.

+9
source share
3 answers

It is expected that the detail node of the error message will contain XML. GetDetail deserializes this XML into the given object.

Since the content is not XML, this method can be used.

However, you can access the XML and read the innerXml value:

 MessageFault msgFault = ex.CreateMessageFault(); var msg = msgFault.GetReaderAtDetailContents().Value; 

It worked.

+13
source
  public void AfterReceiveReply(ref System.ServiceModel.Channels.Message reply, object correlationState) { if (reply.IsFault) { // Create a copy of the original reply to allow default WCF processing MessageBuffer buffer = reply.CreateBufferedCopy(Int32.MaxValue); Message copy = buffer.CreateMessage(); // Create a copy to work with reply = buffer.CreateMessage(); // Restore the original message MessageFault faultex = MessageFault.CreateFault(copy, Int32.MaxValue); //Get Fault from Message FaultCode codigo = faultex.Code; //if (faultex.HasDetail)... //More details buffer.Close(); 
+1
source

Here are some methods I've found to extract this detailed exception information from FaultExceptions

Get the contents of a row of one element

 catch (FaultException e) { var errorElement = XElement.Parse(e.CreateMessageFault().GetReaderAtDetailContents().ReadOuterXml()); var errorDictionary = errorElement.Elements().ToDictionary(key => key.Name.LocalName, val => val.Value); var errorMessage = errorDictionary?["ErrorMessage"]; } 

Output Example:

Organization does not exist.

Get the contents of a row of all parts as one row

 catch (FaultException e) { var errorElement = XElement.Parse(e.CreateMessageFault().GetReaderAtDetailContents().ReadOuterXml()); var errorDictionary = errorElement.Elements().ToDictionary(key => key.Name.LocalName, val => val.Value); var errorDetails = string.Join(";", errorDictionary); } 

Output Example:

[ErrorMessage, organization does not exist.]; [EventCode, 3459046134826139648]; [Parameters,]

Get the string content of the Everything element as an XML string

 var errorElement = XElement.Parse(e.CreateMessageFault().GetReaderAtDetailContents().ReadOuterXml()); var xmlDetail = (string)errorElement; 

Output Example:

 <FaultData xmlns="http://schemas.datacontract.org/2004/07/Xata.Ignition.Common.Contract" xmlns:i="http://www.w3.org/2001/XMLSchema-instance"> <ErrorMessage>Organization does not exist.</ErrorMessage> <EventCode>3459046134826139648</EventCode> <Parameters i:nil="true" xmlns:a="http://schemas.microsoft.com/2003/10/Serialization/Arrays"></Parameters> </FaultData> 
0
source

All Articles