如何获取无类型FaultException的详细信息?

时间:2013-07-05 16:46:07

标签: c# soap

我使用C#从.NET 4.5调用SOAP Web服务,我无法理解如何捕获无类型FaultException的详细信息。

如果Web服务遇到错误,我会收到如下消息:

<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>

要捕获错误,我将调用包装在try / catch块中并捕获FaultException

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

问题在于// ???行:我如何访问FaultException的详细信息,因为我无法使用messageFault.GetDetail<T>(),因为详细信息是无类型的?

对于代码和我没有问题的原因,我使用messageFault.Code.NamemessageFault.Reason.Translations.Single().Text获取它们。

我能够编造的是:

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();

但是除了空引用和编码问题之外,它还是一个怪物。

必须 才能获得详细信息。

1 个答案:

答案 0 :(得分:2)

您可以将详细信息作为XML类型阅读,例如。 XElementXmlElement并使用XPath,Linq to XML处理它或仅将其视为字符串。

在类似的情况下,我使用以下代码来获取一个公认的简单细节元素的内容:

var detail = fault.GetDetail<XElement>();
return detail.Value;
相关问题