문제
제어 할 수없는 알려지지 않은 서버 구현과 통신하는 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 상점에있는 것처럼 아직 이것을 다룰 필요가 없었습니다).
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());
}
}
제휴하지 않습니다 StackOverflow