문제

제어 할 수없는 알려지지 않은 서버 구현과 통신하는 WCF 클라이언트가 있습니다. 이 클라이언트는 마음에 들지 않는 것으로 잘 작동합니다. 부정확 한 비누 결함 메시지가 잘못 형성됩니다. 내가받는 메시지는 다음과 같습니다.

<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 스키마에 따르면 아동 요소는 자격을 갖추지 않아야하며 NED는 다음과 같습니다.

<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 예외 대신 오류 메시지를 소비 할 수 있도록 후자의 형식으로 도착한 메시지를 소비 할 수 있도록 구성하거나 재정의 할 수있는 것이 있습니까?

도움이 되었습니까?

해결책

메시지 검사관을 발견 한 방법을 기억할 수는 없지만 문제를 해결하는 방법이라는 것을 기억할 수 없습니다.

이것 그리고 이것 기사는 검사관을 만들기위한 기반을 제공했으며 다음은 검사관의 고기입니다.

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

다른 팁

불쾌한 응용 프로그램이 사용자 정의 (그리고 잘못 구현 된) 비누 라이브러리를 사용하는 것처럼 보입니다. 다음 기사는 도움이 될 수 있습니다 (나는 순수한 .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