0

UPS RateWS サービス用の .NET 4.5 WCF クライアントを使用して SOAP 1.1 障害詳細要素を取得する際に問題が発生しています。

問題は、faultcode 要素と faultstring 要素が例外のプロパティ.Codeとして正常に戻ってくることです。.Message詳細オブジェクトが正しく逆シリアル化されておらず、常に空の配列です。

UPS Rating 開発者キットの Rates_Pkg_Gnd.zip ファイル SCHEMA-WSDLs ディレクトリから wsdl と xsds を解凍し、ファイル システムの RateWS.wsdl で Visual Studio 2013s の [サービス参照の追加] ダイアログをポイントして、WCF クライアントを生成しています。

実際のワイヤ ソープ障害メッセージは次のようになります。

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

キャッチしようとしSystem.ServiceModel.FaultException<UPS.RateService.ErrorDetailType[]>ましたが、Detail プロパティは常に UPS.RateService.ErrorDetailType[0] の配列です -- サイズはゼロです。

同様に、 a をキャッチして accessFaultExceptionを呼び出すと、ArrayOfErrorDetailType 要素を含む XML オブジェクトが生成され、何も含まれていません。を使用して XmlReader を取得する別の方法では、同じ偽の構造が生成されます。.CreateMessageFault().GetDetail<XmlElement>().GetReaderAtDetailContents()

これはエラー メッセージ xsd です。

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

3 に答える 3

3

これを機能させるために、シーケンス内にダミー要素を追加しました。

<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 が障害を正しくシリアル化できるようにします。これにより、WCF は、フォールト コントラクトで渡される新しいクラス "Errors" を強制的に生成します。FaultException<Errors>その後、例外をキャッチして、 ErrorDetailType[].

于 2016-10-25T20:19:16.653 に答える
0

<detail />最終的に私が見つけた解決策は、要素のコンテンツが定義されないように WSDL を変更しsvcutil、プロキシ クラスの生成に使用することでした。これを行うと、生の<err:Errors />XML 要素にアクセスできます。

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

これにより、XPath を使用して err:Description 要素の内容を取得できます。元の WSDL では、何も得られません。

于 2015-03-23T14:16:35.740 に答える