2009-03-04 1 views
1

私は制御できない未知のサーバー実装と通信する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: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の例外の代わりにフォールトメッセージを消費することができるように、私は後者の形式で到着するメッセージを消費することができるようにオーバーライド?

答えて

4

私はメッセージ検査官に出くわしたが、それはどのように私は私の問題を解決することをどのように思い出すことができませんよ。

Thisthis記事は、インスペクタを作成するための基盤を提供し、そして以下は、インスペクタの肉です:

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

0

問題のアプリケーションがカスタム(および実装が不適切な)SOAPライブラリを使用しているようです。次の記事は役立つかもしれません(私はまだ純粋な.Netの店のようにこれを扱わなければならなかった)。

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

+0

たぶん私は何かを見逃しているが、私はこれは私が、サーバーとクライアントではなくのために何ができるすべてのものであると考えています。私が間違っている場合は私を修正しますが、それはIErrorHandlerの実装を作成する可能性があると思われますが、これはサーバー側にのみ適用されます。 – Dave

0

注System.Web.Services.Protocols.SoapHttpClientProtocolクラスは大幅に思われること WCFよりも誤った形式のフォールト応答を許容します。

これは、ASMXサービス・プロトコルと呼ばれることもあります。それも考慮するオプションかもしれない。

ハワード・ホフマンは

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

} 
+0

あなたのコードに少なくともいくつかの説明をしてください。 –

関連する問題