How can I get the details of an untyped Fault exception?

I am invoking a SOAP web service with .NET 4.5 using C # and I cannot figure out how to catch the details of an untyped FaultException .

If the web service is experiencing an error, I get a message similar to this:

 <S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/"> <S:Body> <S:Fault xmlns:ns4="http://www.w3.org/2003/05/soap-envelope"> <faultcode>GSX.SYS.003</faultcode> <faultstring>Multiple error messages exist. Please check the detail section.</faultstring> <detail> <operationId>HqrCoRMbtKczWFH2WMuFJGe</operationId> <errors> <error> <code>ENT.UPL.005</code> <message>User ID is required for authentication.</message> </error> <error> <code>ENT.UPL.005</code> <message>Password is required for authentication.</message> </error> <error> <code>ENT.UPL.005</code> <message>Sold-To is required for authentication.</message> </error> </errors> </detail> </S:Fault> </S:Body> </S:Envelope> 

To catch the error, I transfer the call to the try / catch block and catch a FaultException :

 try { // Do something. } catch (FaultException faultException) { var messageFault = faultException.CreateMessageFault(); // ??? throw; } 

The problem is the line // ??? : how can I access the details of a FaultException , given that I cannot use messageFault.GetDetail<T>() because the part is untyped?

For code and reason, I have no problem, I get them with messageFault.Code.Name and messageFault.Reason.Translations.Single().Text .

What I could come up with is the following:

 var stringWriter = new StringWriter(); var xmlTextWriter = new XmlTextWriter(stringWriter); var messageFault = faultException.CreateMessageFault(); messageFault.WriteTo(xmlTextWriter, EnvelopeVersion.Soap12); var stringValue = Convert.ToString(stringWriter); var nameTable = new NameTable(); var xmlNamespaceManager = new XmlNamespaceManager(nameTable); xmlNamespaceManager.AddNamespace("soap", "http://www.w3.org/2003/05/soap-envelope"); var xmlDocument = XDocument.Parse(stringValue); var operationId = xmlDocument .XPathSelectElement("/soap:Fault/soap:Detail/operationId", xmlNamespaceManager) .Value; var errors = xmlDocument .XPathSelectElements("/soap:Fault/soap:Detail/errors/error", xmlNamespaceManager) .Select(element => new { Code = element.XPathSelectElement("code").Value, Message = element.XPathSelectElement("message").Value }) .ToArray(); 

But null links and encoding issues aside, this is a monster.

There should be an easier way to get the details.

+4
source share
1 answer

You can read the detail as an XML type, for example. XElement or XmlElement and process it using XPath, Linq to XML or just treat it as a string.

In a similar situation, I use the following code to get the contents of an element with shared rights:

 var detail = fault.GetDetail<XElement>(); return detail.Value; 
+2
source

Source: https://habr.com/ru/post/1489942/


All Articles