2009-03-04 2 views
1

나는 제어 할 수없는 알 수없는 서버 구현과 통신하는 WCF 클라이언트를 가졌습니다. 이 클라이언트는 정상적으로 작동하지 않습니다. SOAP 오류 메시지가 잘못 형성된 것 같습니다. 내가 자식 요소가 자격을 같이하는 네드해서는 안 비누 스키마에 따라 믿고잘못 구성된 오류 메시지를 소비 할 수 있습니까?

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

I 구성 할 수있는 뭔가가 아니면 재정의하여 xml 예외 대신 오류 메시지를 사용할 수 있도록 후자 형식으로 도착하는 메시지를 소비 할 수 있습니까?

답변

4

나는 메시지 사찰을 우연히 발견 어떻게 찾았는지 기억하지 수,하지만 난 내 문제를 해결하는 방법이있다.

Thisthis 글은 관리자를 작성하기위한 기반을 제공하고, 어떤 다음은 관리자의 고기 다음 System.Web.Services.Protocols.SoapHttpClientProtocol 클래스 보인다

 
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

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

적어도 코드에 대한 설명을하시기 바랍니다. –

관련 문제