我成功地使用了第三方肥皂服务。我已经为自动生成类的soap Web服务添加了服务引用。
发生错误时,会返回如下的soap响应:
<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>
我可以捕获错误但不提取详细信息。我尝试了以下代码:
catch (FaultException ex)
{
MessageFault msgFault = ex.CreateMessageFault();
var elm = msgFault.GetDetail<string>();
//throw Detail
}
但是,作为详细信息节点的以下错误不是对象:
Expecting element 'string' from namespace 'http://schemas.datacontract.org/2004/07/MyDemoNamespace'.. Encountered 'Text' with name '', namespace ''.
这是第三方API,因此我无法更改响应。
答案 0 :(得分:12)
消息错误的详细信息节点应包含XML。 GetDetail会将此XML反序列化为给定对象。
由于内容不是XML,因此可以使用此方法。
然而,您可以访问XML并读取innerXml值:
MessageFault msgFault = ex.CreateMessageFault();
var msg = msgFault.GetReaderAtDetailContents().Value;
这接近有效。
答案 1 :(得分:1)
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();
答案 2 :(得分:1)
我发现了几种从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"];
}
提取详细异常信息的方法
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);
}
示例输出:
组织不存在。
var errorElement = XElement.Parse(e.CreateMessageFault().GetReaderAtDetailContents().ReadOuterXml());
var xmlDetail = (string)errorElement;
示例输出:
[ErrorMessage,组织不存在。]; [EventCode,3459046134826139648]; [Parameters,]
<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>
示例输出:
var pointer = obj; for ( key of keysArray) { pointer = pointer[key]} ; console.log(pointer);
答案 3 :(得分:0)
您可以抓住FaultException<TDetail>
,它免费为您提供详细信息。
catch (FaultException<string> ex)
{
string yourDetail = ex.Detail;
}