Calling External Web Services from Salesforce.com – Part IV: Returning an array from the external web service

We went over the basics of invoking an external web service from Salesforce.com Apex code in Parts I, II & III of this series. In this article, we will go over returning an array from the external web service back to Salesforce.com.

Let’s dive into the specifics right away:

  • First, create your asp.net web service (I used Visual Studio 2008). I just created a basic asp.net web service called ArrayWebService, and changed the HelloWorld() method to the “GetArray()” method instead, with a string array as the return type. Here’s my web service code, I have highlighted the important parts:-
Code Snippet
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Web;
  5. using System.Web.Services;
  6.  
  7. namespace ArrayWebService
  8. {
  9.     /// <summary>
  10.     /// Summary description for Service1
  11.     /// </summary>
  12.     [WebService(Namespace = "http://tempuri.org/")]
  13.     [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
  14.     [System.ComponentModel.ToolboxItem(false)]
  15.     public class Service1 : System.Web.Services.WebService
  16.     {
  17.         [WebMethod]
  18.         public string[] GetArray()
  19.         {
  20.             return new String[] {
  21.                 "Empire State Building"
  22.                 , "Rockefeller Center"
  23.                 , "Wall Street"
  24.                 , "World Trade Center"
  25.                 , "Statue Of Liberty" };
  26.         }
  27.     }
  28. }
  • Next, publish your web service. In solution explorer, right-click on the web service, and select publish as shown in Figure 1 below. This is required to “publish” your web service to the local IIS. Prior to doing this, make sure you have a folder called “ArrayWebService” created under your local IIS folder (usually this is C:\InetPub\wwwroot).

image 

  • On the “Publish Web” screen, enter the path as shown in Figure # 2 below. Make sure that the options are selected as shown. Hit Publish – this should copy all of your project files under the C:\InetPub\wwwroot\ArrayWebService folder.                 

image

image

  • You need to now make sure that your web service is now callable by salesforce.com. In order for this to happen, your web service should be “exposed” to the internet. If you are on a company network, you are most likely behind a firewall and salesforce.com will not be able to access your web service. I would like to suggest here that you go through Part II of this article series to understand how to use port forwarding to expose your WS to Salesforce.com.
  • To test if your web service is working correctly, go to http://www.webpagetest.org/, and in the web site address, enter your web service’s address – this should be something like http://{your IP Address}/ArrayWebService/Service1.asmx.  
  • If you are able to run your web service locally, but are having trouble testing it from “webpagetest.org”, it is most likely that your web service is not yet exposed to the internet. Consult the network person at your firm to check how you can fix this.
  • Once you are able to successfully test the WS, try creating a class in Salesforce.com from the web service WSDL – detailed description of this process is covered in Part III of this series – go through it to understand how to create the class on the Salesforce side using your web service WSDL.
  • When you create the class in Salesforce, the code should look like the below. Take special note of the fact that I have modified the IP Address of the web service to go to my machine. Another thing to note here is that the “GetArray” method does not return a string array – instead, it returns an object of type “InvokeArrayWebService.ArrayOfString”. This means that when invoking the method, we will have to write one more extra step to extra the return result from the ArrayOfString return object.
Code Snippet
  1. //Generated by wsdl2apex
  2.  
  3. public class InvokeArrayWebService {
  4.     public class GetArrayResponse_element {
  5.         public InvokeArrayWebService.ArrayOfString GetArrayResult;
  6.         private String[] GetArrayResult_type_info = new String[]{'GetArrayResult','http://tempuri.org/','ArrayOfString','0','1','false'};
  7.         private String[] apex_schema_type_info = new String[]{'http://tempuri.org/','true','false'};
  8.         private String[] field_order_type_info = new String[]{'GetArrayResult'};
  9.     }
  10.     public class GetArray_element {
  11.         private String[] apex_schema_type_info = new String[]{'http://tempuri.org/','true','false'};
  12.         private String[] field_order_type_info = new String[]{};
  13.     }
  14.     public class ArrayOfString {
  15.         public String[] string_x;
  16.         private String[] string_x_type_info = new String[]{'string','http://www.w3.org/2001/XMLSchema','string','0','-1','true'};
  17.         private String[] apex_schema_type_info = new String[]{'http://tempuri.org/','true','false'};
  18.         private String[] field_order_type_info = new String[]{'string_x'};
  19.     }
  20.     public class Service1Soap {
  21.         public String endpoint_x = 'http://76.116.65.169/arraywebservice/service1.asmx';
  22.         public Map<String,String> inputHttpHeaders_x;
  23.         public Map<String,String> outputHttpHeaders_x;
  24.         public String clientCertName_x;
  25.         public String clientCert_x;
  26.         public String clientCertPasswd_x;
  27.         public Integer timeout_x;
  28.         private String[] ns_map_type_info = new String[]{'http://tempuri.org/', 'InvokeArrayWebService'};
  29.         public InvokeArrayWebService.ArrayOfString GetArray() {
  30.             InvokeArrayWebService.GetArray_element request_x = new InvokeArrayWebService.GetArray_element();
  31.             InvokeArrayWebService.GetArrayResponse_element response_x;
  32.             Map<String, InvokeArrayWebService.GetArrayResponse_element> response_map_x = new Map<String, InvokeArrayWebService.GetArrayResponse_element>();
  33.             response_map_x.put('response_x', response_x);
  34.             WebServiceCallout.invoke(
  35.               this,
  36.               request_x,
  37.               response_map_x,
  38.               new String[]{endpoint_x,
  39.               'http://tempuri.org/GetArray',
  40.               'http://tempuri.org/',
  41.               'GetArray',
  42.               'http://tempuri.org/',
  43.               'GetArrayResponse',
  44.               'InvokeArrayWebService.GetArrayResponse_element'}
  45.             );
  46.             response_x = response_map_x.get('response_x');
  47.             return response_x.GetArrayResult;
  48.         }
  49.     }
  50. }
  • Next, I created an anonymous code block with the below piece of code. Take special note of the highlighted portion – since the GetArray() method is returning an object of type “InvokeArrayWebService.ArrayOfString”, we cannot directly access the array being returned. We need to go into the “string_x” object inside the returned object to get the returned array.
Code Snippet
  1. InvokeArrayWebService.Service1Soap s1 = new InvokeArrayWebService.Service1Soap();
  2. InvokeArrayWebService.ArrayOfString arrayofstring;
  3. arrayofstring = s1.GetArray();
  4. String [] returnArray = arrayofstring.string_x;
  5. for(String s: returnArray)
  6. {
  7.     System.Debug('*****************' + s);
  8. }
  • If you look carefully at the class generated from the WSDL, you can figure it out yourself. The ArrayOfString object has a string[] named string_x – this is the object that will contain the return value. You can inspect the “field_order_type_info” object to deduce this.
Code Snippet
  1. public class ArrayOfString {
  2.     public String[] string_x;
  3.     private String[] string_x_type_info = new String[]{'string','http://www.w3.org/2001/XMLSchema','string','0','-1','true'};
  4.     private String[] apex_schema_type_info = new String[]{'http://tempuri.org/','true','false'};
  5.     private String[] field_order_type_info = new String[]{'string_x'};
  6. }
  • So, there you go, this is how you can return an array from an external web service to the Salesforce.com apex class.

No comments:

Post a Comment