[SalesForce] How to invoke soap web service

I have read through the apex developer's guide – webservice section three times but got more confused. Based on my previous knowledge, invoking a Soap webservice should be something like sending an xml request(post) to a wsdl server and get the xml response. So is there any place I can test invoking it that way? Workbench is majorly for Rest service and I have tried SoapUI but got some errors. So is there any way to invoke a Soap wsdl without using AJAX? Simple as the following code:

global class myClass { 
  webService static Id makeContact(String lastName, Account a) { 
        Contact c = new Contact(LastName = lastName, AccountId = a.Id); 
        return c.id; 
    }
}

Best Answer

I had to modify your webservice a bit to get a valid WSDL that SOAPUI could import. When you pass the accountId as the Account type Salesforce adds a whole lot of extra simple and complex types to the WSDL that aren't really needed. The WSDL goes from 6 KB to 542 KB. By sticking with strings or Ids the WSDL is much simpler.

Without any modifications I get the following error from SoupUI:

Error: type 'address@http://soup.sforce.com/schemas/class/DFB/myClass'

This is because there is no complex or simple type address in namespace http://soap.sforce.com/schemas/class/DFB/myClass (alias tns).

Here is my simplified Apex web service:

global class myClass { 
    webService static Id makeContact(String lastName, Id accountId) { 
        Contact c = new Contact(LastName = lastName, AccountId = accountId); 
        insert c;
        System.debug(LoggingLevel.Info, 'Created ' + c.Id + ' for ' + accountId);
        return c.id; 
    }
}

Be sure to save the WSDL directly from the link rather than opening it in the browser and then saving it to disk. I've found browsers can make subtle changes to the WSDL that will sometimes corrupt them.

Saving WSDL directly from link

The resulting WSDL imported into SoupUI successfully for me and I was able to make the following request. Here the SessionID was pulled from an active session using the anonymous apex:

String sessionID = UserInfo.getSessionId();
System.debug(sessionID);

Sample request to same pod as the session was retrieved from:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:myc="http://soap.sforce.com/schemas/class/DFB/myClass">
   <soapenv:Header>
      <myc:SessionHeader>
         <myc:sessionId>00D700000000001!AQoAQGOTA_NOTAREALSESSIONID_Bqf78awnl</myc:sessionId>
      </myc:SessionHeader>
   </soapenv:Header>
   <soapenv:Body>
      <myc:makeContact>
         <myc:lastName>Foo</myc:lastName>
         <myc:accountId>0017000000UolWs</myc:accountId>
      </myc:makeContact>
   </soapenv:Body>
</soapenv:Envelope>

Which gave the response:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns="http://soap.sforce.com/schemas/class/DFB/myClass">
   <soapenv:Body>
      <makeContactResponse>
         <result>003700000000005AAP</result>
      </makeContactResponse>
   </soapenv:Body>
</soapenv:Envelope>
Related Topic