+ Start a Discussion
Ivar@MarelIvar@Marel 

Webservice and problem with WSDL

Hi.
I have a problem that I can't get around in my code. I have a small webservice that receives data from an outside source and uses that to construct a task and associate it with a contact or lead. the webservice has only one method called "logSingleEmail". This method takes a list of a custom class called DocumentLink as one of it's arguments.  Now all tests run normally and I am able to invoke this code successfully from Eclipse as anonymous code. The problem is that the WSDL doesn't list the attributes of the DocumentLink class, and my customer can't invoke the webservice as a result.
Hopefully this is just some small oversight on my behalf that someone can help me with. Included below are both the code from my webservice as well as the generated wsdl:

 

APEX CODE:

 

global class WS_LogCustomerEmail {
	
	static webservice CallResult logSingleEmail( String strCustomerEmail, String strIPadUdid, List<DocumentLink> documents ){
		//lookup lead/contact from strCustomerEmail
		
		Boolean bWasFound = false;
		Contact c = new Contact();
		Lead l = new Lead();
		try{
			l = [Select Id from Lead where Email =: strCustomerEmail limit 1];
		}
		catch( Exception e){
		
	
			try{
				c = [Select Id from Contact where Email =: strCustomerEmail limit 1];
				bWasFound = true;
			}
			catch( Exception ex){
				return new CallResult('Email not found');
			}
			/*if( c != null ) bWasFound = true;
			else return new CallResult('Customer email was not found in Salesforce');
			*/
		}
		
		
		//construct email body from list and strIPadUdid
		String emailBody = 'The following document links were sent via offline catalog:\n\n';
		for( DocumentLink link:documents){
			emailBody += link.strDocumentName + ' - ' + link.strDocumentUrl + '\n';
		}
		emailBody += '\n from user: ' + strIPadUdid;
		
		Task t = new Task();
		if( l.Id != null) t.WhoId = l.Id;
		else if( c.Id != null) t.WhoId = c.Id;
		else return new CallResult('Unknown customer Id');
		
		t.Description = emailBody;
		t.Subject = 'Documents from offline catalog';
		
		try{
			insert t;
		}
		catch ( Exception e){
			return new CallResult(e.getMessage());
		}
		
		return new CallResult('1');	
	}
	
	global class CallResult{
		public String strResult;
		public Callresult( String strIn ){ strResult = strIn; }	
	}
	
	global class DocumentLink{
		public String strDocumentName;
		public String strDocumentUrl;
		
	}
	
	static testMethod void coverCodeForService(){
		Lead l = new Lead();
		l.Email = 'ivargu@thisisjustfortestingpurposes.com';
		l.LastName = 'Gunnarsson';
		l.Company = 'MyCompany';
		insert l;
		
		DocumentLink dl = new DocumentLink();
		dl.strDocumentName = 'Name';
		dl.strDocumentUrl = 'http://www.mbl.is';
		List<DocumentLink> dlList = new List<DocumentLink>();
		dlList.add(dl);
		
		CallResult result = logSingleEmail( 'ivargu@thisisjustfortestingpurposes.com', '12345', dlList );
		
		
	}
}

   WSDL:

This XML file does not appear to have any style information associated with it. The document tree is shown below.
<!-- Web Services API : WS_LogCustomerEmail -->
<definitions xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tns="http://soap.sforce.com/schemas/class/WS_LogCustomerEmail" targetNamespace="http://soap.sforce.com/schemas/class/WS_LogCustomerEmail">
<types>
<xsd:schema elementFormDefault="qualified" targetNamespace="http://soap.sforce.com/schemas/class/WS_LogCustomerEmail">
<xsd:element name="DebuggingInfo">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="debugLog" type="xsd:string"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:simpleType name="ID">
<xsd:restriction base="xsd:string">
<xsd:length value="18"/>
<xsd:pattern value="[a-zA-Z0-9]{18}"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="LogCategory">
<xsd:restriction base="xsd:string">
<xsd:enumeration value="Db"/>
<xsd:enumeration value="Workflow"/>
<xsd:enumeration value="Validation"/>
<xsd:enumeration value="Callout"/>
<xsd:enumeration value="Apex_code"/>
<xsd:enumeration value="Apex_profiling"/>
<xsd:enumeration value="Visualforce"/>
<xsd:enumeration value="System"/>
<xsd:enumeration value="All"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="LogCategoryLevel">
<xsd:restriction base="xsd:string">
<xsd:enumeration value="Internal"/>
<xsd:enumeration value="Finest"/>
<xsd:enumeration value="Finer"/>
<xsd:enumeration value="Fine"/>
<xsd:enumeration value="Debug"/>
<xsd:enumeration value="Info"/>
<xsd:enumeration value="Warn"/>
<xsd:enumeration value="Error"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:complexType name="LogInfo">
<xsd:sequence>
<xsd:element name="category" type="tns:LogCategory"/>
<xsd:element name="level" type="tns:LogCategoryLevel"/>
</xsd:sequence>
</xsd:complexType>
<xsd:simpleType name="LogType">
<xsd:restriction base="xsd:string">
<xsd:enumeration value="None"/>
<xsd:enumeration value="Debugonly"/>
<xsd:enumeration value="Db"/>
<xsd:enumeration value="Profiling"/>
<xsd:enumeration value="Callout"/>
<xsd:enumeration value="Detail"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:element name="DebuggingHeader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="categories" minOccurs="0" maxOccurs="unbounded" type="tns:LogInfo"/>
<xsd:element name="debugLevel" type="tns:LogType"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:element name="CallOptions">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="client" type="xsd:string"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:element name="SessionHeader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="sessionId" type="xsd:string"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:element name="AllowFieldTruncationHeader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="allowFieldTruncation" type="xsd:boolean"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:complexType name="CallResult">
<xsd:sequence/>
</xsd:complexType>
<xsd:complexType name="DocumentLink">
<xsd:sequence/>
</xsd:complexType>
<xsd:element name="logSingleEmail">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="strCustomerEmail" type="xsd:string" nillable="true"/>
<xsd:element name="strIPadUdid" type="xsd:string" nillable="true"/>
<xsd:element name="documents" minOccurs="0" maxOccurs="unbounded" type="tns:DocumentLink" nillable="true"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:element name="logSingleEmailResponse">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="result" type="tns:CallResult" nillable="true"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:schema>
</types>
<!-- Message for the header parts -->
<message name="Header">
<part name="AllowFieldTruncationHeader" element="tns:AllowFieldTruncationHeader"/>
<part name="CallOptions" element="tns:CallOptions"/>
<part name="DebuggingHeader" element="tns:DebuggingHeader"/>
<part name="DebuggingInfo" element="tns:DebuggingInfo"/>
<part name="SessionHeader" element="tns:SessionHeader"/>
</message>
<!-- Operation Messages -->
<message name="logSingleEmailRequest">
<part element="tns:logSingleEmail" name="parameters"/>
</message>
<message name="logSingleEmailResponse">
<part element="tns:logSingleEmailResponse" name="parameters"/>
</message>
<portType name="WS_LogCustomerEmailPortType">
<operation name="logSingleEmail">
<input message="tns:logSingleEmailRequest"/>
<output message="tns:logSingleEmailResponse"/>
</operation>
</portType>
<binding name="WS_LogCustomerEmailBinding" type="tns:WS_LogCustomerEmailPortType">
<soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
<operation name="logSingleEmail">
<soap:operation soapAction=""/>
<input>
<soap:header use="literal" part="SessionHeader" message="tns:Header"/>
<soap:header use="literal" part="CallOptions" message="tns:Header"/>
<soap:header use="literal" part="DebuggingHeader" message="tns:Header"/>
<soap:header use="literal" part="AllowFieldTruncationHeader" message="tns:Header"/>
<soap:body use="literal" parts="parameters"/>
</input>
<output>
<soap:header use="literal" part="DebuggingInfo" message="tns:Header"/>
<soap:body use="literal"/>
</output>
</operation>
</binding>
<service name="WS_LogCustomerEmailService">
<documentation/>
<port binding="tns:WS_LogCustomerEmailBinding" name="WS_LogCustomerEmail">
<soap:address location="https://cs3-api.salesforce.com/services/Soap/class/WS_LogCustomerEmail"/>
</port>
</service>
</definitions>

 Best regards,

Ivar

 

Best Answer chosen by Admin (Salesforce Developers) 
sdetweilsdetweil

the only problem is that on your input and output structures you didn't declare the fields as WebService exposed data

 

my code that works 
global class myOutputs{ webservice String errorMessage; webservice Boolean success; webservice string input; webservice String CaseSubject; webservice String CaseDescription; } like this global class DocumentLink{ webservice String strDocumentName; webservice String strDocumentUrl; }

 
then the WSDL will have all the right info

 

and on CallResult

	global class CallResult{
		webservice String strResult;
		public Callresult( String strIn ){ strResult = strIn; }	
	}

 

All Answers

sdetweilsdetweil

the only problem is that on your input and output structures you didn't declare the fields as WebService exposed data

 

my code that works 
global class myOutputs{ webservice String errorMessage; webservice Boolean success; webservice string input; webservice String CaseSubject; webservice String CaseDescription; } like this global class DocumentLink{ webservice String strDocumentName; webservice String strDocumentUrl; }

 
then the WSDL will have all the right info

 

and on CallResult

	global class CallResult{
		webservice String strResult;
		public Callresult( String strIn ){ strResult = strIn; }	
	}

 

This was selected as the best answer
Ivar@MarelIvar@Marel

Thanks a million, that did the trick :)