function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
savvyboardersavvyboarder 

return xml formatting and WSDL SOAP responses

blank_page

Hi all-

 

I'm wondering if someone can help me figure out the solution to my problem.  I generated an apex class from the WSDL class generator, and this is part of the output. However, I have been told that I will need to ensure the the SOAP responses are described in the WSDL.  I'm not a SOAP expert so I don't know where to begin...  So, I have posted the two types of responses that come back from our web service provider as well as how its defined in the WSDL.   ANY help is greatly appreciated...

 

 

public csCallCenterWS.CreateNewAccountResult_element CreateNewAccount(String strUser,String strPin,Integer lngSiteID,String strFirstName,String strLastName,String strAccountName,String strAccountType,String strAddress1,String strAddress2,String strCity,String strState,String strZip,String strEmail,String strHomePhone) { csCallCenterWS.CreateNewAccount_element request_x = new csCallCenterWS.CreateNewAccount_element(); csCallCenterWS.CreateNewAccountResponse_element response_x; request_x.strUser = strUser; request_x.strPin = strPin; request_x.lngSiteID = lngSiteID; request_x.strFirstName = strFirstName; request_x.strLastName = strLastName; request_x.strAccountName = strAccountName; request_x.strAccountType = strAccountType; request_x.strAddress1 = strAddress1; request_x.strAddress2 = strAddress2; request_x.strCity = strCity; request_x.strState = strState; request_x.strZip = strZip; request_x.strEmail = strEmail; request_x.strHomePhone = strHomePhone; Map<String, csCallCenterWS.CreateNewAccountResponse_element> response_map_x = new Map<String, csCallCenterWS.CreateNewAccountResponse_element>(); response_map_x.put('response_x', response_x); WebServiceCallout.invoke( this, request_x, response_map_x, new String[]{endpoint_x, 'http://centershift.com/csCallCenter/csCallCenterService/CreateNewAccount', 'http://centershift.com/csCallCenter/csCallCenterService', 'CreateNewAccount', 'http://centershift.com/csCallCenter/csCallCenterService', 'CreateNewAccountResponse', 'csCallCenterWS.CreateNewAccountResponse_element'} ); response_x = response_map_x.get('response_x'); return response_x.CreateNewAccountResult; }

 

 

 

EXPECTED XML RESPONSE

 

ERROR

 

      <Error>
        <ErrorCode>100</ErrorCode>
        <Line>445</Line>
        <Message>Failed to log in User:  Either Username or Password is incorrect or User does not have permission</Message>
      </Error>

 

SUCCESS

 

      <Account>
        <FIRST_NAME>frank</FIRST_NAME>
        <LAST_NAME>sinatra</LAST_NAME>
        <EMAIL_ADDRESS>test@example.com</EMAIL_ADDESS>
        <PASSWORD>438500</PASSWORD>
        <CONTACT_ID>5662413</CONTACT_ID>
        <ACCOUNT_ID>3072405</ACCOUNT_ID>
      </Account>

 

 

HERE IS HOW THE RESPONSE IS DEFINED IN THE WSDL

 

      <s:element name="CreateNewAccountResponse">
        <s:complexType>
          <s:sequence>
            <s:element minOccurs="0" maxOccurs="1" name="CreateNewAccountResult">
              <s:complexType mixed="true">
                <s:sequence>
                  <s:any />
                </s:sequence>
              </s:complexType>
            </s:element>
          </s:sequence>
        </s:complexType>
      </s:element>

Message Edited by savvyboarder on 02-02-2009 09:03 AM
Message Edited by savvyboarder on 02-02-2009 09:58 AM
aalbertaalbert

The response type should be defined in the Apex generated code and defined as a class named "CreateNewAccountResult_element"

 

Search for that code within the Apex class and that should show you the class structure for a successfully returned result.

 

For the errors, that class name wasn't provided in the code snippet, but you should also see it within the Apex generated

code as long as it was included in the WSDL. 

 

 

bwinkleskybwinklesky

public class CreateNewAccountResult_element { private String[] apex_schema_type_info = new String[]{'http://centershift.com/csCallCenter/csCallCenterService','true'}; private String[] field_order_type_info = new String[]{}; }

 

 

This is the result element class that was generated, but as you can see the xml elements aren't defined... or at least I can't see it. This is where my ignorance kicks in.  :)

 

Also, the error class isn't generated, because the WSDL doesn't define errors at all.  Can I code it by hand? 

Message Edited by bwinklesky on 02-02-2009 10:02 AM
cheenathcheenath

<Account>
        <FIRST_NAME>frank</FIRST_NAME>
        <LAST_NAME>sinatra</LAST_NAME>
        <EMAIL_ADDRESS>test@example.com</EMAIL_ADDESS>
        <PASSWORD>438500</PASSWORD>
        <CONTACT_ID>5662413</CONTACT_ID>
        <ACCOUNT_ID>3072405</ACCOUNT_ID>
      </Account>

 

Is this this full response? I dont see a SOAP envelope. 

 

 

savvyboardersavvyboarder

The full response looks has another element and looks like this...

 

  <CreateNewAccount>

<Account>
        <FIRST_NAME>frank</FIRST_NAME>
        <LAST_NAME>sinatra</LAST_NAME>
        <EMAIL_ADDRESS>test@example.com</EMAIL_ADDESS>
        <PASSWORD>438500</PASSWORD>
        <CONTACT_ID>5662413</CONTACT_ID>
        <ACCOUNT_ID>3072405</ACCOUNT_ID>
      </Account> 

</CreateNewAccount>

cheenathcheenath

<SOAP-ENV:Envelope
  xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"/>
   <SOAP-ENV:Body>

  <CreateNewAccount>

<Account>
        <FIRST_NAME>frank</FIRST_NAME>
        <LAST_NAME>sinatra</LAST_NAME>
        <EMAIL_ADDRESS>test@example.com</EMAIL_ADDESS>
        <PASSWORD>438500</PASSWORD>
        <CONTACT_ID>5662413</CONTACT_ID>
        <ACCOUNT_ID>3072405</ACCOUNT_ID>
      </Account> 

</CreateNewAccount>

     

    </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

 

 

A soap response should look something like this. So I suspect that the server you are trying out

is not sending back a SOAP response. If that is the case you need to use the HTTP callout. You can find

the doc for this here:

 

http://www.salesforce.com/us/developer/docs/apexcode/index_Left.htm#StartTopic=Content%2Fapex_web_services_wsdl2apex.htm|SkinName=webhelp

 

 

savvyboardersavvyboarder
Thanks cheenath.  It's definitely not sending back a soap response.  I will start digging into the HTTP callout.  Thanks for pointing me in the right direction!!
savvyboardersavvyboarder

Hey cheenath-

 

I'm trying to use the HTTPResponse class that's being used here.  I'm curious how you use the SOAPAction when making a post.  When I use the POST method it using this (https://host02den.centershift.com/pxi/DODCallCenter/csCallCenterService.asmx) as the endpoint i'm getting the following error in the debug logs. 

 

 

<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <soap:Body> <soap:Fault> <faultcode>soap:Client</faultcode> <faultstring>Unable to handle request without a valid action parameter. Please supply a valid soap action.</faultstring> <detail /> </soap:Fault> </soap:Body>

 


 

 

Also, here are the sample SOAP envelopes you are talking about... 

 

https://host02den.centershift.com/pxi/DODCallCenter/csCallCenterService.asmx?op=CreateNewAccount

 

Let me know if you have any ideas or thoughts.

 

Thanks again!  

 

cheenathcheenath

This is a SOAP endpoint:

 

https://host02den.centershift.com/pxi/DODCallCenter/csCallCenterService.asmx?wsdl

 

You should be able to use the stub generated by wsdl2apex. No need to use HTTPRespnse class.

 

What is error you are getting when you use the generated code.

 

 

savvyboardersavvyboarder

This is the error that I get...

 

System.CalloutException: Web service callout failed: Unable to parse callout response. Apex type not found for element CreateNewAccount

Class.csCallCenterWS.csCallCenterSoap.CreateNewAccount: line 490, column 13
Class.csController.CreateNewAccount: line 12, column 64
External entry point

 

 

Perhaps I'm doing something wrong when I'm invoking the service? 

 

 

public void CreateNewAccount() { csCallCenterWS.csCallCenterSoap csWebHost = new csCallCenterWS.csCallCenterSoap(); csCallCenterWS.CreateNewAccountResult_element result = csWebHost.CreateNewAccount('CEISAxis41', 's4axis', 310201, 'FRANK', 'SINATRA', 'SINATRA, FRANK', '295', '123', '123', 'SPRINGFIELD', 'UT', '84121', 'TEST@EXAMPLE.COM', '111-111-1111');

}

 

cheenathcheenath

The way you make the ws call looks good.

 

I took a closer look at the WSDL. It is using schema "any" (s:any) for most of the

types. WS Callout does not support any. Do you know why the the WSDL is defined using

any? 

 

 

 

 

savvyboardersavvyboarder

I don't know why it's defined as any.  To be honest, I'm not sure if there is any rhyme or reason.  Perhaps I can find out... 

 

Is there a way to work around it?  

Message Edited by savvyboarder on 02-02-2009 03:05 PM
savvyboardersavvyboarder

So the only thing that I can figure out is that the web service is intended to be used with the .NET framework and they use the "s:any" attribute for flexibility.  The biggest reason I can see the use of the any attribute is that the service returns two different xml responses depending on whether its an error or success. 

 

1) ERROR

 

<CreateNewAccount>

      <Error>
        <ErrorCode>100</ErrorCode>
        <Line>445</Line>
        <Message>Failed to log in User:  Either Username or Password is incorrect or User does not have permission</Message>
      </Error>

 </CreateNewAccount>

 

2)  SUCCESS

 

 <CreateNewAccount>

      <Account>
        <FIRST_NAME>frank</FIRST_NAME>
        <LAST_NAME>sinatra</LAST_NAME>
        <EMAIL_ADDRESS>test@example.com</EMAIL_ADDESS>
        <PASSWORD>438500</PASSWORD>
        <CONTACT_ID>5662413</CONTACT_ID>
        <ACCOUNT_ID>3072405</ACCOUNT_ID>
      </Account>

 </CreateNewAccount>

 

 

Is there even be a way to work around this style of WSDL in SFDC?  

 

cheenathcheenath

xsd:any means server can return any XML. There is no good way to map this to APEX right now. So it is not supported.

 

If there is an error, a service should returns a SOAP Fault. It is not a good practice to change the response XML.

 

 

savvyboardersavvyboarder
Ok. Thanks for the help!! 
dgrigsbydgrigsby

savvyboard,

 

I added this info on another similar post of yours as well.

 

I just went down this journey recently, and yes there are lots of "clean up" items and limitiations going the WSDL2APEX path.

 

I have done a large post on the subject. Please review and comment on as appropriate.

 

 
or
 

 

1. WSDL - I would highly suggest using a WSDL/XML tool like Atlova XMLSpy (free trial) to examine the Types that are imported. It will allow you to trim down, and integrate the imported (manually - wish they had a merge - going to post that feature request at Atlova) xsd types, etc. I normally work with Visual Studio or Eclipse and they just couldn't get there. It will show you what is in the namespace and what is imported in the WDSL tab visually by color coding.

 

      a. WSDL Apex Class creation Limitations

          -Size of final Apex Class - 100K characters
        -Size of WSDL input - 1Meg
          - No Imports and no implied types from defined named spaces if they contain definitions (xsd which ws-security does).
           -No Attributes (xsd which ws-security does).
           -No annotations (xsd which ws-security does).

           -No multipe bindings (which most do 1 and 12)

 

2. Be prepared to spend some time (read as parse, fix error, rise and repeat) many times

3. Best SF reference I found was Link:

4. In the end, you may find to get it working that the HTTP request and manual soap xml codeup to be the quickest solution to get it running, Twitter and Facebook integrations work this way. It was really faster in the end for me.

5. The post covers both WSDL2APEX and Direct Soap calls via HTTP Request and examples so that you can choose the best option for your integration needs and handle varying return responses.

 

Best Regards,

 

 

David W. Grigsby
Grigsby Consulting LLC
Intellectual Capital for Your Business
484 East Carmel Drive Suite 390
Carmel, IN 46032
 
 
venkatSanthanamvenkatSanthanam

Hello,

How was this problem of s:any resolved ?

 

I am encountering the same problem now. Any help would be much appreciated.

 

I am using the centershift webservice and CreateNewAccount and hitting the same error. I would appreciate any help on this.

 

 

Thanks

Venkat

venkatSanthanamvenkatSanthanam

This problem is not resolved for me yet. Any help would be much appreciated.

 

Thanks

Venkat

savvyboardersavvyboarder
We actually ended up writing our own web service wrapper that spit out the return values that we could use in Salesforce.com.  
venkatSanthanamvenkatSanthanam

Hi,

Thanks for responding to the post. It would be nice if you could please direct me in the direction for wring this myself. Considering the fact that, I am going to consume the same webservice, Would that be something that you can provide me?

 

Thanks

Venkat