不正な形式の障害メッセージを消費することは可能ですか?

StackOverflow https://stackoverflow.com/questions/610902

  •  03-07-2019
  •  | 
  •  

質問

WCFクライアントが不明なサーバー実装と通信しているが、それを制御することはできません。このクライアントは正常に動作しますが、見た目が間違っていて、誤って形成されたSOAP Faultメッセージが好きではありません。私が受け取るメッセージは次のようになります。

<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">   
    <soap:Header>...</soap:Header>  
    <soap:Body>  
        <soap:Fault>  
            <soap:faultcode>soap:Client</soap:faultcode>  
            <soap:faultstring>...</soap:faultstring>  
            <soap:detail>...</soap:detail>  
        </soap:Fault>  
    </soap:Body>  
</soap:Envelope>  

SOAPスキーマによれば、子要素は次のように修飾されてはいけないと考えられます。

<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">   
    <soap:Header>...</soap:Header>  
    <soap:Body>  
        <soap:Fault>  
            <faultcode>soap:Client</faultcode>  
            <faultstring>...</faultstring>  
            <detail>...</detail>  
        </soap:Fault>  
    </soap:Body> 
</soap:Envelope>

XML例外の代わりに障害メッセージを消費できるように、後者の形式で到着するメッセージを消費できるように、構成またはオーバーライドできるものはありますか?

役に立ちましたか?

解決

Message Inspectorsで偶然見つけた方法を思い出せませんが、問題を解決した方法です。

これおよびこのの記事は、インスペクターを作成するための基礎を提供しました。次は検査官の肉です:

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

    var document = new 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))
    {
        do
        {
            var c = it.Current;

            if (string.IsNullOrEmpty(c.Prefix))
                continue;

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

            /// we may want to record the detail included inside the detail element, 
            /// it is not reported in the FaultException that is raised.

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

    reply = fixedReply;
}

他のヒント

問題のあるアプリケーションがカスタム(および実装が不適切な)SOAPライブラリを使用しているようです。次の記事が役立つかもしれません(純粋な.Netショップにいるので、これについてはまだ対処する必要がありません)。

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

System.Web.Services.Protocols.SoapHttpClientProtocolクラスは、WCFよりも不正なフォールトレスポンスに対して大幅に耐性があるようです。

これは、ASMXサービスプロトコルと呼ばれることもあります。それも考慮すべき選択肢かもしれません。

ハワード・ホフマン

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

}
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top