4

WCF アプリケーションを開発していますが、サービスの 1 つで、Java で開発されたサード パーティの Web サービスを使用する必要があります。サードパーティのサービスは政府によって提供されており、そのコードにアクセスしたり、変更を求めたりすることはほとんど不可能です。

wsdl からサービス参照として追加すると、参照が自動的に生成されます。

メソッド呼び出しは機能しているように見えますが、障害をキャッチしようとすると、サード パーティ サービスによって提供されるカスタム障害データを取得できません。FaultException で取得できるのは、「処理中にエラーが発生しました」だけです。(これだけでメッセージと理由の両方が設定されます。)

wsdl にはカスタムの障害タイプがありますが、.NET は返された SOAP 応答をそのタイプの FaultException にマップできないようです。したがって、私のコードは、一般的なメッセージと HasDetails=false を含む一般的な FaultException を取得するだけです。

政府の Web サービスから返されたエラーの種類をクライアントに示す義務があるため、これは私たちにとって問題です。

あなたたちは、私が打ち負かすことができる何かを台無しにしていると思いますか? 私はすでにイライラしているので、どんなアドバイスも大歓迎です。ここに私のコードからのチャンクがあります:

try
{
    //this is the 3rd party Java web service
    EFaturaPortTypeClient efService = new EFaturaPortTypeClient();

    //setting here the object to be sent to the 3rd party web service

    var returnVal = efService.sendDocument(docRequest);
}
catch (FaultException<EFaturaFaultType> ex)
{
    //need to get the "Reason" or "Detail" from the returned soap fault
    //but cannot even get in here
}
catch (FaultException ex)
{
    //this is where the debug goes

    //tried below method, but retrieves nothing worthy
    MessageFault mf = ex.CreateMessageFault();

    throw new FaultException<EFaturaFaultType>(mf.GetDetail<EFaturaFaultType>());
}

そして、これが私がスニッフィングした障害の SOAP 応答です。

<?xml version="1.0" encoding="UTF-8"?>
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope">
   <soap:Body>
      <soap:Fault>
         <soap:Code>
            <soap:Value>soap:Receiver</soap:Value>
         </soap:Code>
         <soap:Reason>
            <soap:Text xml:lang="en">2006:GECERSIZ ZARF ADI</soap:Text>
         </soap:Reason>
         <soap:Detail>
            <ns3:EFaturaFault xmlns:ns3="http://gib.gov.tr/vedop3/eFatura" xmlns:xmime="http://www.w3.org/2005/05/xmlmime">
               <code>2006</code>
               <msg>GECERSIZ ZARF ADI</msg>
            </ns3:EFaturaFault>
         </soap:Detail>
      </soap:Fault>
   </soap:Body>
</soap:Envelope>

最後に、サード パーティの Web サービスの wsdl を次に示します。

<?xml version='1.0' encoding='UTF-8'?><wsdl:definitions name="EFatura" targetNamespace="http://gib.gov.tr/vedop3/eFatura" xmlns:ns1="http://schemas.xmlsoap.org/soap/http" xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/" xmlns:tns="http://gib.gov.tr/vedop3/eFatura" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <wsdl:types>
<xs:schema targetNamespace="http://www.w3.org/2005/05/xmlmime" version="1.0" xmlns:tns="http://www.w3.org/2005/05/xmlmime" xmlns:xs="http://www.w3.org/2001/XMLSchema">
   <xs:complexType name="base64Binary">
      <xs:simpleContent>
         <xs:extension base="xs:base64Binary">
            <xs:attribute ref="tns:contentType" />
         </xs:extension>
      </xs:simpleContent>
   </xs:complexType>
   <xs:complexType name="hexBinary">
      <xs:simpleContent>
         <xs:extension base="xs:string">
            <xs:attribute ref="tns:contentType" />
         </xs:extension>
      </xs:simpleContent>
   </xs:complexType>
   <xs:attribute name="contentType" type="xs:string" />
</xs:schema><xs:schema targetNamespace="http://gib.gov.tr/vedop3/eFatura" version="1.0" xmlns:ns1="http://www.w3.org/2005/05/xmlmime" xmlns:tns="http://gib.gov.tr/vedop3/eFatura" xmlns:xs="http://www.w3.org/2001/XMLSchema">
   <xs:import namespace="http://www.w3.org/2005/05/xmlmime" />
   <xs:element name="EFaturaFault" type="tns:EFaturaFaultType" />
   <xs:element name="documentRequest" type="tns:documentType" />
   <xs:element name="documentResponse" type="tns:documentReturnType" />
   <xs:element name="getAppRespRequest" type="tns:getAppRespRequestType" />
   <xs:element name="getAppRespResponse" type="tns:getAppRespResponseType" />
   <xs:complexType name="getAppRespRequestType">
      <xs:sequence>
         <xs:element minOccurs="0" name="instanceIdentifier" type="xs:string" />
      </xs:sequence>
   </xs:complexType>
   <xs:complexType name="getAppRespResponseType">
      <xs:sequence>
         <xs:element minOccurs="0" name="applicationResponse" type="xs:string" />
      </xs:sequence>
   </xs:complexType>
   <xs:complexType name="EFaturaFaultType">
      <xs:sequence>
         <xs:element minOccurs="0" name="code" type="xs:int" />
         <xs:element minOccurs="0" name="msg" type="xs:string" />
      </xs:sequence>
   </xs:complexType>
   <xs:complexType name="documentType">
      <xs:sequence>
         <xs:element minOccurs="0" name="fileName" type="xs:string" />
         <xs:element minOccurs="0" name="binaryData" type="ns1:base64Binary" />
         <xs:element minOccurs="0" name="hash" type="xs:string" />
      </xs:sequence>
   </xs:complexType>
   <xs:complexType name="documentReturnType">
      <xs:sequence>
         <xs:element minOccurs="0" name="msg" type="xs:string" />
         <xs:element minOccurs="0" name="hash" type="xs:string" />
      </xs:sequence>
   </xs:complexType>
</xs:schema>  </wsdl:types>
  <wsdl:message name="EFaturaFaultMessage">
    <wsdl:part element="tns:EFaturaFault" name="EFaturaFaultMessage">
    </wsdl:part>
  </wsdl:message>
  <wsdl:message name="sendDocument">
    <wsdl:part element="tns:documentRequest" name="document">
    </wsdl:part>
  </wsdl:message>
  <wsdl:message name="getApplicationResponse">
    <wsdl:part element="tns:getAppRespRequest" name="getApplicationResponseRequestPart">
    </wsdl:part>
  </wsdl:message>
  <wsdl:message name="getApplicationResponseResponse">
    <wsdl:part element="tns:getAppRespResponse" name="getApplicationResponseResponsePart">
    </wsdl:part>
  </wsdl:message>
  <wsdl:message name="sendDocumentResponse">
    <wsdl:part element="tns:documentResponse" name="sendDocumentReturn">
    </wsdl:part>
  </wsdl:message>
  <wsdl:portType name="EFaturaPortType">
    <wsdl:operation name="getApplicationResponse">
      <wsdl:input message="tns:getApplicationResponse" name="getApplicationResponse">
    </wsdl:input>
      <wsdl:output message="tns:getApplicationResponseResponse" name="getApplicationResponseResponse">
    </wsdl:output>
      <wsdl:fault message="tns:EFaturaFaultMessage" name="EFaturaFaultMessage">
    </wsdl:fault>
    </wsdl:operation>
    <wsdl:operation name="sendDocument">
      <wsdl:input message="tns:sendDocument" name="sendDocument">
    </wsdl:input>
      <wsdl:output message="tns:sendDocumentResponse" name="sendDocumentResponse">
    </wsdl:output>
      <wsdl:fault message="tns:EFaturaFaultMessage" name="EFaturaFaultMessage">
    </wsdl:fault>
    </wsdl:operation>
  </wsdl:portType>
  <wsdl:binding name="EFaturaSoapBinding" type="tns:EFaturaPortType">
    <soap12:binding style="document" transport="http://schemas.xmlsoap.org/soap/http" />
    <wsdl:operation name="getApplicationResponse">
      <soap12:operation soapAction="getApplicationResponse" style="document" />
      <wsdl:input name="getApplicationResponse">
        <soap12:body use="literal" />
      </wsdl:input>
      <wsdl:output name="getApplicationResponseResponse">
        <soap12:body use="literal" />
      </wsdl:output>
      <wsdl:fault name="EFaturaFaultMessage">
        <soap12:fault name="EFaturaFaultMessage" use="literal" />
      </wsdl:fault>
    </wsdl:operation>
    <wsdl:operation name="sendDocument">
      <soap12:operation soapAction="sendDocument" style="document" />
      <wsdl:input name="sendDocument">
        <soap12:body use="literal" />
      </wsdl:input>
      <wsdl:output name="sendDocumentResponse">
        <soap12:body use="literal" />
      </wsdl:output>
      <wsdl:fault name="EFaturaFaultMessage">
        <soap12:fault name="EFaturaFaultMessage" use="literal" />
      </wsdl:fault>
    </wsdl:operation>
  </wsdl:binding>
  <wsdl:service name="EFatura">
    <wsdl:port binding="tns:EFaturaSoapBinding" name="EFaturaSoap12">
      <soap12:address location="https://merkeztest.efatura.gov.tr/EFaturaMerkez/services/EFatura" />
    </wsdl:port>
  </wsdl:service>
</wsdl:definitions>

編集: 自動生成された Reference.cs の関連部分:

[System.CodeDom.Compiler.GeneratedCodeAttribute("System.Xml", "4.0.30319.18408")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(Namespace = "http://gib.gov.tr/vedop3/eFatura", TypeName = "EFaturaFaultType")]
public partial class EFaturaFaultType : object, System.ComponentModel.INotifyPropertyChanged {

    private int codeField;

    private bool codeFieldSpecified;

    private string msgField;

    /// <remarks/>
    [System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified, Order=0)]
    public int code {
        get {
            return this.codeField;
        }
        set {
            this.codeField = value;
            this.RaisePropertyChanged("code");
        }
    }

    /// <remarks/>
    [System.Xml.Serialization.XmlIgnoreAttribute()]
    public bool codeSpecified {
        get {
            return this.codeFieldSpecified;
        }
        set {
            this.codeFieldSpecified = value;
            this.RaisePropertyChanged("codeSpecified");
        }
    }

    /// <remarks/>
    [System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified, Order=1)]
    public string msg {
        get {
            return this.msgField;
        }
        set {
            this.msgField = value;
            this.RaisePropertyChanged("msg");
        }
    }

    public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged;

    protected void RaisePropertyChanged(string propertyName) {
        System.ComponentModel.PropertyChangedEventHandler propertyChanged = this.PropertyChanged;
        if ((propertyChanged != null)) {
            propertyChanged(this, new System.ComponentModel.PropertyChangedEventArgs(propertyName));
        }
    }
}

[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0"
[System.ServiceModel.ServiceContractAttribute(Namespace="http://gib.gov.tr/vedop3/eFatura", ConfigurationName="EFService.EFaturaPortType")]
public interface EFaturaPortType {

    [System.ServiceModel.OperationContractAttribute(Action="sendDocument", ReplyAction="*")]
    [System.ServiceModel.FaultContractAttribute(typeof(BF.EFService.EFaturaFaultType), Action="sendDocument", Name="EFaturaFault")]
    [System.ServiceModel.XmlSerializerFormatAttribute(SupportFaults=true)]
    BF.EFService.sendDocumentResponse sendDocument(BF.EFService.sendDocument request);
4

2 に答える 2

1

Visual Studio のソリューション エクスプローラーでサービス参照ノードを右クリックし、[常にメッセージ コントラクトを生成する] チェック ボックスをオンにして、実際にこれを解決しました。どうやってそこにたどり着いたのか聞かないでください...知っている場合にのみ説明できました。その後、生成されたクラスとメソッドが変更され、問題はなくなります。ただし、明らかに、生成されたサービス プロキシを介して渡された null パラメーターによって引き起こされるエラーに固有のものではありません。

お役に立てば幸いです。

于 2014-02-27T13:44:24.400 に答える
1

まだ定義していない場合は、EFaturaFaultTypeクラスを属性で定義し、DataContractシリアライズ可能なメンバーを属性でマークする必要があると思いますDataMember

次のリンクは、WCF エラー処理の確かな概要を提供します。 http://www.codeproject.com/Articles/26320/WCF-Error-Handling-and-Fault-Conversion

よろしく、

于 2014-02-25T18:49:32.170 に答える