Pregunta

Estoy desarrollando una aplicación WCF, y uno de mis servicios necesita consumir un 3er partido de servicio web desarrollado en Java.La 3ª parte el servicio es prestado por el gobierno y es casi imposible llegar a su código / pedir el cambio.

Lo he añadido como un Servicio de Referencia de su wsdl, y la referencia es generado automáticamente.

La llamada al método parece funcionar, pero cuando trato de atrapar a los fallos, yo soy incapaz de obtener la costumbre de falla de los datos proporcionados por el servicio de 3 ª parte. Todo lo que puedo conseguir en FaultException es "Fallo se produjo durante el procesamiento." (mensaje y la razón son ambos solo con esto.)

El wsdl tiene una costumbre tipo de fallo, pero se parece .NET no se puede asignar la devolución de JABÓN respuesta a una FaultException con ese tipo.Por lo tanto, mi código sólo se pone un genérico FaultException con un mensaje genérico y HasDetails=false.

Bueno, esto es un problema para nosotros ya que estamos obligados a mostrar a nuestros clientes ¿qué tipo de falla fue devuelto desde la web del gobierno de servicio.

¿Ustedes piensan que estoy jugando con algo comparable?Cualquier consejo es muy apreciado como ya estoy frustrado.Aquí es un fragmento de mi código:

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

Y aquí es una respuesta SOAP de culpa que olfateó:

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

y finalmente aquí está el wsdl de la 3ª parte del servicio web:

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

Editar:La parte pertinente del auto generado Referencia.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);
¿Fue útil?

Solución

Realmente resolví esto haciendo clic derecho en el nodo de referencia de servicio en el Explorador de soluciones en Visual Studio y verificando la casilla Siempre genera contratos de mensajes .No me preguntes cómo llegué allí ... Solo pude explicar si lo supiera.Las clases y métodos generados cambian después de eso, y el problema desaparece.Aunque, aparentemente, aún no es específico sobre los errores causados por los parámetros nulos pasados a través del proxy de servicio generado.

Espero que ayude.

Otros consejos

Creo que es posible que necesite definir, si no lo ha hecho ya, el EFaturaFaultType clase con el DataContract atributo y marcar cualquier serializable miembros con el DataMember atributo.

El siguiente enlace proporciona una sólida visión general de WCF Manejo de Errores. http://www.codeproject.com/Articles/26320/WCF-Error-Handling-and-Fault-Conversion

Saludos,

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top