1

我有一个 WCF 客户端与我无法控制的未知服务器实现进行通信。这个客户端工作正常,只是不喜欢,看起来是,格式不正确的 SOAP 错误消息。我收到的消息如下所示:

<soap:信封 xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">   
    <soap:Header>...</soap:Header>  
    <肥皂:身体>  
        <soap:故障>  
            <soap:faultcode>soap:Client</soap:faultcode>  
            <soap:faultstring>...</soap:faultstring>  
            <soap:detail>...</soap:detail>  
        </soap:故障>  
    </肥皂:身体>  
</soap:信封>  

我相信根据soap模式,子元素不应该被限定并且看起来像:

<soap:信封 xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">   
    <soap:Header>...</soap:Header>  
    <肥皂:身体>  
        <soap:故障>  
            <faultcode>soap:客户端</faultcode>  
            <故障字符串>...</故障字符串>  
            <详细>...</详细>  
        </soap:故障>  
    </肥皂:身体>
</soap:信封>

有什么我可以配置或覆盖的东西,以便我可以使用以后一种格式到达的消息,以便我可以使用错误消息而不是 xml 异常?

4

4 回答 4

4

我不记得我是如何偶然发现消息检查器的,但它是我如何解决我的问题的。

这篇这篇文章为创建检查器提供了基础,以下是检查器的核心:

public void AfterReceiveReply(ref Message reply, object correlationState)
{
    if (!reply.IsFault)
        返回;

    var 文档 = 新的 XmlDocument();

    document.Load(reply.GetReaderAtBodyContents());

    var navigator = document.CreateNavigator();
    var manager = new XmlNamespaceManager(navigator.NameTable);

    manager.AddNamespace("soap", "http://schemas.xmlsoap.org/soap/envelope/");

    var it = navigator.Select("//soap:Fault", manager);

    if (it.MoveNext() && it.Current.HasChildren && it.Current.MoveToChild(XPathNodeType.Element))
    {
        做
        {
            var c = it.Current;

            if (string.IsNullOrEmpty(c.Prefix))
                继续;

            c.ReplaceSelf("<" + c.LocalName + ">" + c.InnerXml + "</" + c.LocalName + ">");

            /// 我们可能想要记录包含在细节元素中的细节,
            /// 它不会在引发的 FaultException 中报告。

        } 而 (it.Current.MoveToNext());
    }

    var reader = XmlDictionaryReader.CreateDictionaryReader(new XmlNodeReader(document));

    reader.MoveToStartElement();

    var fixedReply = Message.CreateMessage(reply.Version, null, reader);

    fixedReply.Headers.CopyHeadersFrom(reply.Headers);
    fixedReply.Properties.CopyProperties(reply.Properties);

    回复 = 固定回复;
}

于 2009-03-05T22:48:21.127 回答
0

看起来有问题的应用程序正在使用自定义(并且实现不佳)的 SOAP 库。下面的文章可能会有所帮助(到目前为止,我还没有处理这个问题,因为我在一个纯 .Net 商店)。

http://msdn.microsoft.com/en-us/library/ms733721.aspx

于 2009-03-04T15:00:26.000 回答
0

请注意,System.Web.Services.Protocols.SoapHttpClientProtocol 类似乎WCF 更能容忍格式错误的故障响应。

这有时被称为 ASMX 服务协议。这也可能是一个可以考虑的选择。

霍华德霍夫曼

于 2010-04-06T18:57:50.453 回答
0
} catch (SoapFaultClientException e) {
    log.error(e);
    SoapFaultDetail soapFaultDetail = e.getSoapFault().getFaultDetail();
    SoapFaultDetailElement detailElementChild = (SoapFaultDetailElement) soapFaultDetail.getDetailEntries().next();
    Source detailSource = detailElementChild.getSource();

    try {
        Object detail = (JAXBElement<SearchResponse>) getWebServiceTemplate().getUnmarshaller().unmarshal(detailSource);
//                throw new SoapFaultWithDetailException(detail);

    } catch (IOException e1) {
        throw new IllegalArgumentException("cannot unmarshal SOAP fault detail object: " + soapFaultDetail.getSource());
    }

}
于 2015-09-15T14:47:08.910 回答