Hello,

We are trying to build a C++ client to connect to WCF services using 
basicHttpBinding.

I am able to use WSDL2C to generate the C++ stub and use the stub calls to send 
request to the service and get result object back.
But I am unable to get the Fault object back. It seems to me the generated stub 
can not handle the Soap Fault object.
I am wondering if any one can give me some help for receiving Fault object. 

My service WSDL contains the service call GetData(string) and fault class 
BatchService:
   <wsdl:binding name="WSHttpBinding_IBatchService" type="i0:IBatchService">
    <wsp:PolicyReference URI="#WSHttpBinding_IBatchService_policy" />
    <soap12:binding transport="http://schemas.xmlsoap.org/soap/http"; />
    <wsdl:operation name="GetData">
      <soap12:operation soapAction="" style="document" />
      <wsdl:input>
        <wsp:PolicyReference 
URI="#WSHttpBinding_IBatchService_GetData_Input_policy" />
        <soap12:body use="literal" />
      </wsdl:input>
      <wsdl:output>
        <wsp:PolicyReference 
URI="#WSHttpBinding_IBatchService_GetData_output_policy" />
        <soap12:body use="literal" />
      </wsdl:output>
      <wsdl:fault name="BatchFaultFault">
        <wsp:PolicyReference 
URI="#WSHttpBinding_IBatchService_GetData_BatchFaultFault_Fault" />
        <soap12:fault use="literal" name="BatchFaultFault" namespace="" />
      </wsdl:fault>
    </wsdl:operation>
</wsdl:binding>

WSDL2C does generate the following files:
    axis2_stub_BatchService.[hc]
    adb_GetData.[hc]
    adb_BatchFault.[hc]

However the stub request function axis2_stub_op_BatchService_GetData() inside 
the geratated file axis2_stub_BatchService.c does not check if there is any 
fault. The function has the following lines:
            ret_node =  axis2_svc_client_send_receive_with_op_qname( 
svc_client, env, op_qname, payload);
            ret_val = adb_GetDataResponse_create(env);
            if(adb_GetDataResponse_deserialize(ret_val, env, &ret_node, NULL, 
AXIS2_FALSE ) == AXIS2_FAILURE)

If the soap xml is BatchFault instead of regular return object, the  
adb_GetDataResponse_deserialize() call would fail and 
axis2_stub_op_BatchService_GetData() call return NULL. Thus We are unable to 
get the Fault information. 

If I add "xml =  axiom_node_sub_tree_to_string(ret_node, env);" after the line 
of
    ret_node =  axis2_svc_client_send_receive_with_op_qname( svc_client, env, 
op_qname, payload);

I do see the return XML as:
    <s:Fault xmlns:s="http://schemas.xmlsoap.org/soap/envelope/";>
        <faultcode>s:Client</faultcode>
        <faultstring         xmlns:xml="http://www.w3.org/XML/1998/namespace"; 
xml:lang="en-US">
            The creator of this fault did not specify a Reason.</faultstring>
        <detail>
            <BatchFault 
xmlns="http://schemas.datacontract.org/2004/07/eGlue.WCF.Common"; 
xmlns:i="http://www.w3.org/2001/XMLSchema-instance";>
                <ErrorCode>1</ErrorCode>
                <ErrorMessage>Batch Fault: Input value is too big. Expected 
value is less than 1000</ErrorMessage>
            </BatchFault>
        </detail>
    </s:Fault>
So should the stub provide some mechnism to return the custom Fault object or 
throw exception of custom Fault object?

Also I tried to modify the generated stub code to get the BatchFault object 
from the return node. But I am still unable to deserialize into BatchFault 
object.
Both xmls for subtree of <detail> and <BatchFault> are empty and 
adb_BatchFault_deserialize() call fails also. Can you please check what is 
wrong in my code?

The code that I added into axis2_stub_op_BatchService_GetData() function is as 
following:
   if(adb_GetDataResponse_deserialize(ret_val, env, &ret_node, NULL, 
AXIS2_FALSE ) == AXIS2_FAILURE)
    {
      if ( axis2_svc_client_get_last_response_has_fault(svc_client, env) )
      {
       axiom_element_t* data_element = axiom_node_get_data_element(ret_node, 
env);
       if ( data_element != NULL )
       {
        adb_BatchFault_t* fault = NULL;
        axutil_qname_t* detail_qname = NULL;
        axutil_qname_t* batch_fault_qname = NULL;
        axiom_element_t * detail_elementp = NULL;
        axiom_node_t * detail_nodep = axiom_node_create(env);
        axiom_element_t * batch_fault_elementp = NULL;
        axiom_node_t * batch_fault_nodep = axiom_node_create(env);
        detail_qname = axutil_qname_create(env, "detail", NULL, "");
        batch_fault_qname = axutil_qname_create(env, "BatchFault", NULL, "");
        
        detail_elementp = 
axiom_element_get_first_child_with_qname(data_element, env, detail_qname,  
ret_node, &detail_nodep);
        if ( detail_elementp != NULL )
        {
         xml =  axiom_node_sub_tree_to_string(detail_elementp, env);
         batch_fault_elementp = 
axiom_element_get_first_child_with_qname(detail_elementp, env, 
batch_fault_qname,  ret_node, &batch_fault_nodep);
         if ( batch_fault_elementp != NULL )
         {
          xml =  axiom_node_sub_tree_to_string(batch_fault_elementp, env);
          fault = adb_BatchFault_create(env);
          if ( adb_BatchFault_deserialize(fault, env, &batch_fault_nodep, NULL, 
AXIS2_FALSE ) == AXIS2_FAILURE)
          {
           printf("Got unknown exception" );
          }
          else {
           printf("BatchFault: %s\n", adb_BatchFault_get_ErrorMessage(fault, 
env));
          }         
        }
      }

Thank you very much for your help.

Jay




---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to