2014-11-24 1 views
0

UPS RateWS 서비스 용 .NET 4.5 WCF 클라이언트를 사용하여 SOAP 1.1 오류 세부 요소를 가져 오는 데 문제가 있습니다.UPS RateWS 서비스 오류 예외가있는 WCF. <T> 항상 빈 배열

오류 코드 및 faultstring 요소가 예외로 .Code.Message 속성으로 정상적으로 돌아 오는 동안 문제가되는 것입니다. 세부 개체가 올바르게 deserialize되지 않고 항상 빈 배열입니다.

UPS Rating developer kit Rates_Pkg_Gnd.zip 파일 SCHEMA-WSDLs 디렉토리에서 wsdl 및 xsds의 압축을 풀고 내 파일 시스템의 RateWS.wsdl에서 Visual Studio 2013s 서비스 참조 추가 대화 상자를 가리켜 WCF 클라이언트를 생성 중입니다. 내가 System.ServiceModel.FaultException<UPS.RateService.ErrorDetailType[]>을 잡기 시도

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"> 
    <soapenv:Header /> 
    <soapenv:Body> 
    <soapenv:Fault> 
     <faultcode>Client</faultcode> 
     <faultstring>An exception has been raised as a result of client data.</faultstring> 
     <detail> 
     <err:Errors xmlns:err="http://www.ups.com/XMLSchema/XOLTWS/Error/v1.1"> 
      <err:ErrorDetail> 
      <err:Severity>Hard</err:Severity> 
      <err:PrimaryErrorCode> 
       <err:Code>111285</err:Code> 
       <err:Description>The postal code 21740 is invalid for AB Canada.</err:Description> 
      </err:PrimaryErrorCode> 
      </err:ErrorDetail> 
     </err:Errors> 
     </detail> 
    </soapenv:Fault> 
    </soapenv:Body> 
</soapenv:Envelope> 

하지만 상세 속성은 항상 UPS.RateService.ErrorDetailType [0]의 배열입니다 - 제로의 크기 :

실제의 와이어 비누 오류 메시지는 다음과 같습니다.

FaultException도 마찬가지로 .GetDetail<XmlElement>()에 액세스하려면 .CreateMessageFault()을 호출하면 아무 것도없는 ArrayOfErrorDetailType 요소가 포함 된 XML 객체가 생성됩니다. .GetReaderAtDetailContents()을 사용하여 XmlReader를 얻는 다른 방법은 동일한 가짜 구조를 만듭니다. 내가 찾은

<?xml version="1.0" encoding="utf-8"?> 
<xsd:schema xmlns:error="http://www.ups.com/XMLSchema/XOLTWS/Error/v1.1" elementFormDefault="qualified" targetNamespace="http://www.ups.com/XMLSchema/XOLTWS/Error/v1.1" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> 
    <xsd:element name="Errors"> 
    <xsd:complexType> 
     <xsd:sequence> 
     <xsd:element maxOccurs="unbounded" name="ErrorDetail" type="error:ErrorDetailType" /> 
     </xsd:sequence> 
    </xsd:complexType> 
    </xsd:element> 
    <xsd:complexType name="ErrorDetailType"> 
    <xsd:sequence> 
     <xsd:element name="Severity" type="xsd:string" /> 
     <xsd:element name="PrimaryErrorCode" type="error:CodeType" /> 
     <xsd:element minOccurs="0" name="MinimumRetrySeconds" type="xsd:string" /> 
     <xsd:element minOccurs="0" name="Location" type="error:LocationType" /> 
     <xsd:element minOccurs="0" maxOccurs="unbounded" name="SubErrorCode" type="error:CodeType" /> 
     <xsd:element minOccurs="0" maxOccurs="unbounded" name="AdditionalInformation" type="error:AdditionalInfoType" /> 
    </xsd:sequence> 
    </xsd:complexType> 
    <xsd:complexType name="CodeType"> 
    <xsd:sequence> 
     <xsd:element name="Code" type="xsd:string" /> 
     <xsd:element name="Description" type="xsd:string" /> 
     <xsd:element minOccurs="0" name="Digest" type="xsd:string" /> 
    </xsd:sequence> 
    </xsd:complexType> 
    <xsd:complexType name="AdditionalInfoType"> 
    <xsd:sequence> 
     <xsd:element name="Type" type="xsd:string" /> 
     <xsd:element maxOccurs="unbounded" name="Value" type="error:AdditionalCodeDescType" /> 
    </xsd:sequence> 
    </xsd:complexType> 
    <xsd:complexType name="AdditionalCodeDescType"> 
    <xsd:sequence> 
     <xsd:element name="Code" type="xsd:string" /> 
     <xsd:element minOccurs="0" name="Description" type="xsd:string" /> 
    </xsd:sequence> 
    </xsd:complexType> 
    <xsd:complexType name="LocationType"> 
    <xsd:sequence> 
     <xsd:element minOccurs="0" name="LocationElementName" type="xsd:string" /> 
     <xsd:element minOccurs="0" name="XPathOfElement" type="xsd:string" /> 
     <xsd:element minOccurs="0" name="OriginalValue" type="xsd:string" /> 
    </xsd:sequence> 
    </xsd:complexType> 
</xsd:schema> 

답변

0

궁극적으로 솔루션은 <detail /> 요소의 내용이 정의되지 않도록 WSDL을 수정하고 프록시 클래스를 생성 svcutil를 사용했다 :

이 오류 메시지 XSD입니다. 나는이 작업을 수행 할 때, 나는 원시 <err:Errors /> XML 요소에 액세스 할 수 있습니다 : 설명 요소 : 나를 ERR의 내용을 얻기 위해 XPath를 사용할 수 있습니다

var fault = ex.CreateMessageFault(); 
var faultXml = fault.GetDetail<XmlElement>(); 

. 원래 WSDL을 사용하면 아무 것도 얻을 수 없습니다.

2

하면이 나는 순서 안에 더미 요소를 추가 작업을 효율적으로 활용하려면 다음 WCF가 제대로 오류를 직렬화 할 수 있습니다 어떤 이유

<xsd:element name="Errors"> 
    <xsd:complexType> 
     <xsd:sequence> 
      <xsd:element name="ErrorDetail" type="error:ErrorDetailType" maxOccurs="unbounded"/> 
      <xsd:element name="TestElement" type="xsd:string" minOccurs="0"/> 
     </xsd:sequence> 

    </xsd:complexType> 
</xsd:element> 

. 이로 인해 WCF는 오류 계약에 전달되는 새로운 클래스 "오류"를 생성합니다. 그런 다음 FaultException<Errors> 예외를 잡아서 ErrorDetailType[]에 액세스 할 수 있습니다.