4

I am trying to import a WSDL in salesforce which contains Multi-part messages.

Multi-part messages are not supported by the wsdl2Apex tool. The suggested workaround is to modify the WSDL to generate an apex class and keeping the request-response XML structure the same.

I tried starting with the embeddedAsync.init method where I added an extra class to wrap all the parts messages. however, the callout fails with an exception

System.CalloutException: Web service callout failed: WebService returned a SOAP Fault: Unexpected element {http://webservice.embedded.server.qa.encoway.com/}init found. Expected {http://webservice.embedded.server.qa.encoway.com/}WebserviceSessionId. faultcode=soap:Client faultactor=

I am new to the SOAP API world and would like to understand how the multipart WSDL be consumed in apex.

A simple example would be of great help.

Here are the WSDL and the generated code in which I modified embeddedAsync.init method: Sample Code

4
  • 1
    You might want to show with WSDL examples that you tried the mentioned workaround and failed with another issue. Otherwise, I fear that eager moderators will close this a "duplicate". – Robert Sösemann Aug 20 '20 at 10:29
  • 1
    Its a really big WSDL and generated apex code, I have linked it as a gist: gist.github.com/anmolgkv/bf9bd0acdc6924982397a8e9e28c89f8 – Anmol Kumar Aug 20 '20 at 11:42
  • 1
    Doesn't Daniel Balinger's FuseIT tool overcome this issue? – Bryan Anderson Aug 20 '20 at 11:58
  • I tried the FuseIT explorer app as well, got the same error while parsing WSDL – Anmol Kumar Aug 20 '20 at 12:01
3

Unfortunately I don't think you are going to be able to use wsdl2apex and the corresponding WebServiceCallout.invoke() to call these multipart methods.

As you have observed, the init message is comprised of 4 parts:

  1. sessionId
  2. taskId
  3. initContext
  4. callbackContext

But WebServiceCallout.invoke() will only accept a single request parameter as the second argument.

You might be able to promote all but one of the parts into headers as per Importing UPS Street Address WSDL into Apex, but that would depend on what the target web service is expecting.


There are a couple of challenges with this WSDL:

  1. The schema defines a targetNamespace, but omits the xmlns attribute.
  2. There are several elements in the schema that are defined as complex types that have a nested element also defined by a complex type. E.g. AsyncActivateResult > activateResult.

(1) was easily resolved by adding an xmlns attribute on the schema to match the targetNamespace.

<xs:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:tns="http://webservice.embedded.server.qa.backend.com/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" attributeFormDefault="unqualified" elementFormDefault="unqualified" 
            targetNamespace="http://webservice.embedded.server.qa.backend.com/" 
            xmlns="http://webservice.embedded.server.qa.backend.com/" 
            version="1.0">

(2) was resolved by extracting the nested complexType elements are promoting them to direct descendants of the schema. Then the elements use the resulting type as a reference rather than trying to nest the complexType.

<!-- Created this complex type from the content of activateResult -->
<xs:complexType name="activateResultType">
    <xs:complexContent>
        <xs:extension base="tns:SaveResultType">
            <xs:sequence>
                <xs:element minOccurs="0" name="printedDocument" type="tns:ActivationAttachment"/>
                <xs:element minOccurs="0" name="exportFormat" type="tns:ActivationAttachment"/>
            </xs:sequence>
        </xs:extension>
    </xs:complexContent>
</xs:complexType>

<xs:element name="AsyncActivateResult">
    <xs:complexType>
        <xs:sequence>
            <xs:element name="phase" type="xs:int"/>
            <xs:element minOccurs="0" name="activateResult" type="activateResultType">
                <!--<xs:complexType> has been un-nested -->
            </xs:element>
        </xs:sequence>
    </xs:complexType>
</xs:element>

The resulting Apex class - webserviceEmbeddedServerQaBackendCo.cls

1
  • 1
    Thanks for the explanation! I found this stackoverflow.com/a/10598098/4019177 which suggests Wrapping multiple parts in a single document. I believe this will solve the issue but would need some change in the backend – Anmol Kumar Aug 21 '20 at 7:15

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.