axis-c-user mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Jay Qiu <jqi...@yahoo.com>
Subject Question about receiving custom Fault object at Axis2/C client
Date Thu, 31 Jul 2008 13:14:43 GMT
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: axis-c-user-unsubscribe@ws.apache.org
For additional commands, e-mail: axis-c-user-help@ws.apache.org


Mime
View raw message