Step 4: Walk Through the Sample Code

Once you have imported your WSDL file, you can begin building client applications that use the API.

Use the following samples to create a basic client application. Comments embedded in the sample explain each section of code.

Java Sample Code

This section walks through a sample Java client application that uses the WSC SOAP client. The purpose of this sample application is to show the required steps for logging into the login server and to demonstrate the invocation and subsequent handling of several API calls.

To run this sample, you must pass the authentication endpoint URL as an argument for your program. You can obtain this URL from the WSDL file. This sample application performs the following main tasks:

  1. Prompts the user for their Salesforce username and password.
  2. Calls login() to log in to the single login server and, if the login succeeds, retrieves user information and writes it to the console along with session information.
  3. Calls describeGlobal() to retrieve a list of all available objects for the organization’s data. The describeGlobal method determines the objects that are available to the logged in user. This call should not be made more than once per session, since the data returned from the call is not likely to change frequently. The DescribeGlobalResult is echoed to the console.
  4. Calls describeSObjects() to retrieve metadata (field list and object properties) for a specified object. The describeSObject method illustrates the type of metadata information that can be obtained for each object available to the user. The sample client application executes a describeSObjects() call on the object that the user specifies and then echoes the returned metadata information to the console. Object metadata information includes permissions, field types and lengths, and available values for picklist fields and types for referenceTo fields.
  5. Calls query(), passing a simple query string ("SELECT FirstName, LastName FROM Contact"), and iterating through the returned QueryResult.
  6. Calls logout() to the log the user out.

The following sample code uses try/catch blocks to handle exceptions that might be thrown by the API calls.

1package com.example.samples;
2
3import java.io.BufferedReader;
4import java.io.FileNotFoundException;
5import java.io.InputStreamReader;
6import java.io.IOException;
7import com.sforce.soap.enterprise.DeleteResult;
8import com.sforce.soap.enterprise.DescribeGlobalResult;
9import com.sforce.soap.enterprise.DescribeGlobalSObjectResult;
10import com.sforce.soap.enterprise.DescribeSObjectResult;
11import com.sforce.soap.enterprise.EnterpriseConnection;
12import com.sforce.soap.enterprise.Error;
13import com.sforce.soap.enterprise.Field;
14import com.sforce.soap.enterprise.FieldType;
15import com.sforce.soap.enterprise.GetUserInfoResult;
16import com.sforce.soap.enterprise.LoginResult;
17import com.sforce.soap.enterprise.PicklistEntry;
18import com.sforce.soap.enterprise.QueryResult;
19import com.sforce.soap.enterprise.SaveResult;
20import com.sforce.soap.enterprise.sobject.Account;
21import com.sforce.soap.enterprise.sobject.Contact;
22import com.sforce.soap.enterprise.sobject.SObject;
23import com.sforce.ws.ConnectorConfig;
24import com.sforce.ws.ConnectionException;
25
26public class QuickstartApiSample {
27
28   private static BufferedReader reader = new BufferedReader(
29         new InputStreamReader(System.in));
30
31   EnterpriseConnection connection;
32   String authEndPoint = "";
33
34   public static void main(String[] args) {
35      if (args.length < 1) {
36         System.out.println("Usage: com.example.samples."
37               + "QuickstartApiSamples <AuthEndPoint>");
38
39         System.exit(-1);
40      }
41
42      QuickstartApiSample sample = new QuickstartApiSample(args[0]);
43      sample.run();
44   }
45
46   public void run() {
47      // Make a login call
48      if (login()) {
49         // Do a describe global
50         describeGlobalSample();
51
52         // Describe an object
53         describeSObjectsSample();
54
55         // Retrieve some data using a query
56         querySample();
57
58         // Log out
59         logout();
60      }
61   }
62
63   // Constructor
64   public QuickstartApiSample(String authEndPoint) {
65      this.authEndPoint = authEndPoint;
66   }
67
68   private String getUserInput(String prompt) {
69      String result = "";
70      try {
71         System.out.print(prompt);
72         result = reader.readLine();
73      } catch (IOException ioe) {
74         ioe.printStackTrace();
75      }
76
77      return result;
78   }
79
80   private boolean login() {
81      boolean success = false;
82      String username = getUserInput("Enter username: ");
83      String password = getUserInput("Enter password: ");
84
85      try {
86         ConnectorConfig config = new ConnectorConfig();
87         config.setUsername(username);
88         config.setPassword(password);
89
90         System.out.println("AuthEndPoint: " + authEndPoint);
91         config.setAuthEndpoint(authEndPoint);
92
93         connection = new EnterpriseConnection(config);
94         printUserInfo(config);
95
96         success = true;
97      } catch (ConnectionException ce) {
98         ce.printStackTrace();
99      } 
100
101      return success;
102   }
103
104   private void printUserInfo(ConnectorConfig config) {
105      try {
106         GetUserInfoResult userInfo = connection.getUserInfo();
107
108         System.out.println("\nLogging in ...\n");
109         System.out.println("UserID: " + userInfo.getUserId());
110         System.out.println("User Full Name: " + userInfo.getUserFullName());
111         System.out.println("User Email: " + userInfo.getUserEmail());
112         System.out.println();
113         System.out.println("SessionID: " + config.getSessionId());
114         System.out.println("Auth End Point: " + config.getAuthEndpoint());
115         System.out
116               .println("Service End Point: " + config.getServiceEndpoint());
117         System.out.println();
118      } catch (ConnectionException ce) {
119         ce.printStackTrace();
120      }
121   }
122
123   private void logout() {
124      try {
125         connection.logout();
126         System.out.println("Logged out.");
127      } catch (ConnectionException ce) {
128         ce.printStackTrace();
129      }
130   }
131
132   /**
133    * To determine the objects that are available to the logged-in user, the
134    * sample client application executes a describeGlobal call, which returns
135    * all of the objects that are visible to the logged-in user. This call
136    * should not be made more than once per session, as the data returned from
137    * the call likely does not change frequently. The DescribeGlobalResult is
138    * simply echoed to the console.
139    */
140   private void describeGlobalSample() {
141      try {
142         // describeGlobal() returns an array of object results that
143         // includes the object names that are available to the logged-in user.
144         DescribeGlobalResult dgr = connection.describeGlobal();
145
146         System.out.println("\nDescribe Global Results:\n");
147         // Loop through the array echoing the object names to the console
148         for (int i = 0; i < dgr.getSobjects().length; i++) {
149            System.out.println(dgr.getSobjects()[i].getName());
150         }
151      } catch (ConnectionException ce) {
152         ce.printStackTrace();
153      }
154   }
155
156   /**
157    * The following method illustrates the type of metadata information that can
158    * be obtained for each object available to the user. The sample client
159    * application executes a describeSObject call on a given object and then
160    * echoes the returned metadata information to the console. Object metadata
161    * information includes permissions, field types and length and available
162    * values for picklist fields and types for referenceTo fields.
163    */
164   private void describeSObjectsSample() {
165      String objectToDescribe = getUserInput("\nType the name of the object to "
166            + "describe (try Account): ");
167
168      try {
169         // Call describeSObjects() passing in an array with one object type
170         // name
171         DescribeSObjectResult[] dsrArray = connection
172               .describeSObjects(new String[] { objectToDescribe });
173
174         // Since we described only one sObject, we should have only
175         // one element in the DescribeSObjectResult array.
176         DescribeSObjectResult dsr = dsrArray[0];
177
178         // First, get some object properties
179         System.out.println("\n\nObject Name: " + dsr.getName());
180
181         if (dsr.getCustom())
182            System.out.println("Custom Object");
183         if (dsr.getLabel() != null)
184            System.out.println("Label: " + dsr.getLabel());
185
186         // Get the permissions on the object
187
188         if (dsr.getCreateable())
189            System.out.println("Createable");
190         if (dsr.getDeletable())
191            System.out.println("Deleteable");
192         if (dsr.getQueryable())
193            System.out.println("Queryable");
194         if (dsr.getReplicateable())
195            System.out.println("Replicateable");
196         if (dsr.getRetrieveable())
197            System.out.println("Retrieveable");
198         if (dsr.getSearchable())
199            System.out.println("Searchable");
200         if (dsr.getUndeletable())
201            System.out.println("Undeleteable");
202         if (dsr.getUpdateable())
203            System.out.println("Updateable");
204
205         System.out.println("Number of fields: " + dsr.getFields().length);
206
207         // Now, retrieve metadata for each field
208         for (int i = 0; i < dsr.getFields().length; i++) {
209            // Get the field
210            Field field = dsr.getFields()[i];
211
212            // Write some field properties
213            System.out.println("Field name: " + field.getName());
214            System.out.println("\tField Label: " + field.getLabel());
215
216            // This next property indicates that this
217            // field is searched when using
218            // the name search group in SOSL
219            if (field.getNameField())
220               System.out.println("\tThis is a name field.");
221
222            if (field.getRestrictedPicklist())
223               System.out.println("This is a RESTRICTED picklist field.");
224
225            System.out.println("\tType is: " + field.getType());
226
227            if (field.getLength() > 0)
228               System.out.println("\tLength: " + field.getLength());
229
230            if (field.getScale() > 0)
231               System.out.println("\tScale: " + field.getScale());
232
233            if (field.getPrecision() > 0)
234               System.out.println("\tPrecision: " + field.getPrecision());
235
236            if (field.getDigits() > 0)
237               System.out.println("\tDigits: " + field.getDigits());
238
239            if (field.getCustom())
240               System.out.println("\tThis is a custom field.");
241
242            // Write the permissions of this field
243            if (field.getNillable())
244               System.out.println("\tCan be nulled.");
245            if (field.getCreateable())
246               System.out.println("\tCreateable");
247            if (field.getFilterable())
248               System.out.println("\tFilterable");
249            if (field.getUpdateable())
250               System.out.println("\tUpdateable");
251
252            // If this is a picklist field, show the picklist values
253            if (field.getType().equals(FieldType.picklist)) {
254               System.out.println("\t\tPicklist values: ");
255               PicklistEntry[] picklistValues = field.getPicklistValues();
256
257               for (int j = 0; j < field.getPicklistValues().length; j++) {
258                  System.out.println("\t\tValue: "
259                        + picklistValues[j].getValue());
260               }
261            }
262
263            // If this is a foreign key field (reference),
264            // show the values
265            if (field.getType().equals(FieldType.reference)) {
266               System.out.println("\tCan reference these objects:");
267               for (int j = 0; j < field.getReferenceTo().length; j++) {
268                  System.out.println("\t\t" + field.getReferenceTo()[j]);
269               }
270            }
271            System.out.println("");
272         }
273      } catch (ConnectionException ce) {
274         ce.printStackTrace();
275      }
276   }
277
278   private void querySample() {
279      String soqlQuery = "SELECT FirstName, LastName FROM Contact";
280      try {
281         QueryResult qr = connection.query(soqlQuery);
282         boolean done = false;
283
284         if (qr.getSize() > 0) {
285            System.out.println("\nLogged-in user can see "
286                  + qr.getRecords().length + " contact records.");
287
288            while (!done) {
289               System.out.println("");
290               SObject[] records = qr.getRecords();
291               for (int i = 0; i < records.length; ++i) {
292                  Contact con = (Contact) records[i];
293                  String fName = con.getFirstName();
294                  String lName = con.getLastName();
295
296                  if (fName == null) {
297                     System.out.println("Contact " + (i + 1) + ": " + lName);
298                  } else {
299                     System.out.println("Contact " + (i + 1) + ": " + fName
300                           + " " + lName);
301                  }
302               }
303
304               if (qr.isDone()) {
305                  done = true;
306               } else {
307                  qr = connection.queryMore(qr.getQueryLocator());
308               }
309            }
310         } else {
311            System.out.println("No records found.");
312         }
313      } catch (ConnectionException ce) {
314         ce.printStackTrace();
315      }
316   }
317}

C# Sample Code

This section walks through a sample C# client application. The purpose of this sample application is to show the required steps for logging in and to demonstrate the invocation and subsequent handling of several API calls.

This sample application performs the following main tasks:

  1. Prompts the user for their Salesforce username and password.
  2. Calls login() to log in to the single login server and, if the login succeeds:
    • Sets the returned sessionId into the session header, which is required for session authentication on subsequent API calls.
    • Resets the Lightning Platform endpoint to the returned serverUrl, which is the target of subsequent API calls.

      All client applications that access the API must complete the tasks in this step before attempting any subsequent API calls.

    • Retrieves user information and writes it to the console along with session information.
  3. Calls describeGlobal() to retrieve a list of all available objects for the organization’s data. The describeGlobal method determines the objects that are available to the logged in user. This call should not be made more than once per session, since the data returned from the call is not likely to change frequently. The DescribeGlobalResult is echoed to the console.
  4. Calls describeSObjects() to retrieve metadata (field list and object properties) for a specified object. The describeSObject method illustrates the type of metadata information that can be obtained for each object available to the user. The sample client application executes a describeSObjects() call on the object that the user specifies and then echoes the returned metadata information to the console. Object metadata information includes permissions, field types and lengths, and available values for picklist fields and types for referenceTo fields.
  5. Calls query(), passing a simple query string ("SELECT FirstName, LastName FROM Contact"), and iterating through the returned QueryResult.
  6. Calls logout() to the log the user out.

The following sample code uses try/catch blocks to handle exceptions that might be thrown by the API calls.

The following code begins the sample C# client application.

1using System;
2using System.Collections.Generic;
3using System.Linq;
4using System.Text;
5using System.Web.Services.Protocols;
6using Walkthrough.sforce;
7
8namespace Walkthrough
9{
10
11   class QuickstartApiSample
12   {
13      private SforceService binding;
14
15      [STAThread]
16      static void Main(string[] args)
17      {
18         QuickstartApiSample sample = new QuickstartApiSample();
19         sample.run();
20      }
21
22      public void run()
23      {
24         // Make a login call 
25         if (login())
26         {
27            // Do a describe global 
28            describeGlobalSample();
29
30            // Describe an account object 
31            describeSObjectsSample();
32
33            // Retrieve some data using a query 
34            querySample();
35
36            // Log out
37            logout();
38         }
39      }
40
41      private bool login()
42      {
43         Console.Write("Enter username: ");
44         string username = Console.ReadLine();
45         Console.Write("Enter password: ");
46         string password = Console.ReadLine();
47
48         // Create a service object 
49         binding = new SforceService();
50
51         // Timeout after a minute 
52         binding.Timeout = 60000;
53
54         // Try logging in   
55         LoginResult lr;
56         try
57         {
58
59            Console.WriteLine("\nLogging in...\n");
60            lr = binding.login(username, password);
61         }
62
63         // ApiFault is a proxy stub generated from the WSDL contract when     
64         // the web service was imported 
65         catch (SoapException e)
66         {
67            // Write the fault code to the console 
68            Console.WriteLine(e.Code);
69
70            // Write the fault message to the console 
71            Console.WriteLine("An unexpected error has occurred: " + e.Message);
72
73            // Write the stack trace to the console 
74            Console.WriteLine(e.StackTrace);
75
76            // Return False to indicate that the login was not successful 
77            return false;
78         }
79
80
81
82         // Check if the password has expired 
83         if (lr.passwordExpired)
84         {
85            Console.WriteLine("An error has occurred. Your password has expired.");
86            return false;
87         }
88
89
90         /** Once the client application has logged in successfully, it will use
91          * the results of the login call to reset the endpoint of the service
92          * to the virtual server instance that is servicing your organization
93          */
94         // Save old authentication end point URL
95         String authEndPoint = binding.Url;
96         // Set returned service endpoint URL
97         binding.Url = lr.serverUrl;
98
99         /** The sample client application now has an instance of the SforceService
100          * that is pointing to the correct endpoint. Next, the sample client
101          * application sets a persistent SOAP header (to be included on all
102          * subsequent calls that are made with SforceService) that contains the
103          * valid sessionId for our login credentials. To do this, the sample
104          * client application creates a new SessionHeader object and persist it to
105          * the SforceService. Add the session ID returned from the login to the
106          * session header
107          */
108         binding.SessionHeaderValue = new SessionHeader();
109         binding.SessionHeaderValue.sessionId = lr.sessionId;
110
111         printUserInfo(lr, authEndPoint);
112
113         // Return true to indicate that we are logged in, pointed  
114         // at the right URL and have our security token in place.     
115         return true;
116      }
117
118      private void printUserInfo(LoginResult lr, String authEP)
119      {
120         try
121         {
122            GetUserInfoResult userInfo = lr.userInfo;
123
124            Console.WriteLine("\nLogging in ...\n");
125            Console.WriteLine("UserID: " + userInfo.userId);
126            Console.WriteLine("User Full Name: " +
127                userInfo.userFullName);
128            Console.WriteLine("User Email: " +
129                userInfo.userEmail);
130            Console.WriteLine();
131            Console.WriteLine("SessionID: " +
132                lr.sessionId);
133            Console.WriteLine("Auth End Point: " +
134                authEP);
135            Console.WriteLine("Service End Point: " +
136                lr.serverUrl);
137            Console.WriteLine();
138         }
139         catch (SoapException e)
140         {
141            Console.WriteLine("An unexpected error has occurred: " + e.Message +
142                " Stack trace: " + e.StackTrace);
143         }
144      }
145
146      private void logout()
147      {
148         try
149         {
150            binding.logout();
151            Console.WriteLine("Logged out.");
152         }
153         catch (SoapException e)
154         {
155            // Write the fault code to the console 
156            Console.WriteLine(e.Code);
157
158            // Write the fault message to the console 
159            Console.WriteLine("An unexpected error has occurred: " + e.Message);
160
161            // Write the stack trace to the console 
162            Console.WriteLine(e.StackTrace);
163         }
164      }
165
166      /**
167      * To determine the objects that are available to the logged-in
168      * user, the sample client application executes a describeGlobal
169      * call, which returns all of the objects that are visible to
170      * the logged-in user. This call should not be made more than
171      * once per session, as the data returned from the call likely
172      * does not change frequently. The DescribeGlobalResult is
173      * simply echoed to the console.
174      */
175      private void describeGlobalSample()
176      {
177         try
178         {
179            // describeGlobal() returns an array of object results that  
180            // includes the object names that are available to the logged-in user. 
181            DescribeGlobalResult dgr = binding.describeGlobal();
182
183            Console.WriteLine("\nDescribe Global Results:\n");
184            // Loop through the array echoing the object names to the console             
185            for (int i = 0; i < dgr.sobjects.Length; i++)
186            {
187               Console.WriteLine(dgr.sobjects[i].name);
188            }
189         }
190         catch (SoapException e)
191         {
192            Console.WriteLine("An exception has occurred: " + e.Message +
193                "\nStack trace: " + e.StackTrace);
194         }
195      }
196
197      /**
198      * The following method illustrates the type of metadata
199      * information that can be obtained for each object available
200      * to the user. The sample client application executes a
201      * describeSObject call on a given object and then echoes  
202      * the returned metadata information to the console. Object
203      * metadata information includes permissions, field types
204      * and length and available values for picklist fields
205      * and types for referenceTo fields.
206      */
207      private void describeSObjectsSample()
208      {
209         Console.Write("\nType the name of the object to " +
210             "describe (try Account): ");
211         string objectType = Console.ReadLine();
212         try
213         {
214
215            // Call describeSObjects() passing in an array with one object type name 
216            DescribeSObjectResult[] dsrArray =
217                  binding.describeSObjects(new string[] { objectType });
218
219            // Since we described only one sObject, we should have only
220            // one element in the DescribeSObjectResult array.
221            DescribeSObjectResult dsr = dsrArray[0];
222
223            // First, get some object properties                  
224            Console.WriteLine("\n\nObject Name: " + dsr.name);
225
226            if (dsr.custom) Console.WriteLine("Custom Object");
227            if (dsr.label != null) Console.WriteLine("Label: " + dsr.label);
228
229            // Get the permissions on the object 
230            if (dsr.createable) Console.WriteLine("Createable");
231            if (dsr.deletable) Console.WriteLine("Deleteable");
232            if (dsr.queryable) Console.WriteLine("Queryable");
233            if (dsr.replicateable) Console.WriteLine("Replicateable");
234            if (dsr.retrieveable) Console.WriteLine("Retrieveable");
235            if (dsr.searchable) Console.WriteLine("Searchable");
236            if (dsr.undeletable) Console.WriteLine("Undeleteable");
237            if (dsr.updateable) Console.WriteLine("Updateable");
238
239            Console.WriteLine("Number of fields: " + dsr.fields.Length);
240
241            // Now, retrieve metadata for each field
242            for (int i = 0; i < dsr.fields.Length; i++)
243            {
244               // Get the field 
245               Field field = dsr.fields[i];
246
247               // Write some field properties
248               Console.WriteLine("Field name: " + field.name);
249               Console.WriteLine("\tField Label: " + field.label);
250
251               // This next property indicates that this  
252               // field is searched when using 
253               // the name search group in SOSL 
254               if (field.nameField)
255                  Console.WriteLine("\tThis is a name field.");
256
257               if (field.restrictedPicklist)
258                  Console.WriteLine("This is a RESTRICTED picklist field.");
259
260               Console.WriteLine("\tType is: " + field.type.ToString());
261
262               if (field.length > 0)
263                  Console.WriteLine("\tLength: " + field.length);
264
265               if (field.scale > 0)
266                  Console.WriteLine("\tScale: " + field.scale);
267
268               if (field.precision > 0)
269                  Console.WriteLine("\tPrecision: " + field.precision);
270
271               if (field.digits > 0)
272                  Console.WriteLine("\tDigits: " + field.digits);
273
274               if (field.custom)
275                  Console.WriteLine("\tThis is a custom field.");
276
277               // Write the permissions of this field
278               if (field.nillable) Console.WriteLine("\tCan be nulled.");
279               if (field.createable) Console.WriteLine("\tCreateable");
280               if (field.filterable) Console.WriteLine("\tFilterable");
281               if (field.updateable) Console.WriteLine("\tUpdateable");
282
283               // If this is a picklist field, show the picklist values   
284               if (field.type.Equals(fieldType.picklist))
285               {
286                  Console.WriteLine("\tPicklist Values");
287                  for (int j = 0; j < field.picklistValues.Length; j++)
288                     Console.WriteLine("\t\t" + field.picklistValues[j].value);
289               }
290
291               // If this is a foreign key field (reference),     
292               // show the values 
293               if (field.type.Equals(fieldType.reference))
294               {
295                  Console.WriteLine("\tCan reference these objects:");
296                  for (int j = 0; j < field.referenceTo.Length; j++)
297                     Console.WriteLine("\t\t" + field.referenceTo[j]);
298               }
299               Console.WriteLine("");
300            }
301         }
302         catch (SoapException e)
303         {
304            Console.WriteLine("An exception has occurred: " + e.Message +
305                "\nStack trace: " + e.StackTrace);
306         }
307         Console.WriteLine("Press ENTER to continue...");
308         Console.ReadLine();
309      }
310
311      private void querySample()
312      {
313         String soqlQuery = "SELECT FirstName, LastName FROM Contact";
314         try
315         {
316            QueryResult qr = binding.query(soqlQuery);
317            bool done = false;
318
319            if (qr.size > 0)
320            {
321               Console.WriteLine("Logged-in user can see "
322                     + qr.records.Length + " contact records.");
323
324               while (!done)
325               {
326                  Console.WriteLine("");
327                  sObject[] records = qr.records;
328                  for (int i = 0; i < records.Length; i++)
329                  {
330                     Contact con = (Contact)records[i];
331                     string fName = con.FirstName;
332                     string lName = con.LastName;
333                     if (fName == null)
334                        Console.WriteLine("Contact " + (i + 1) + ": " + lName);
335                     else
336                        Console.WriteLine("Contact " + (i + 1) + ": " + fName
337                               + " " + lName);
338                  }
339
340                  if (qr.done)
341                  {
342                     done = true;
343                  }
344                  else
345                  {
346                     qr = binding.queryMore(qr.queryLocator);
347                  }
348               }
349            }
350            else
351            {
352               Console.WriteLine("No records found.");
353            }
354         }
355         catch (Exception ex)
356         {
357            Console.WriteLine("\nFailed to execute query succesfully," +
358                "error message was: \n{0}", ex.Message);
359         }
360         Console.WriteLine("\nPress ENTER to continue...");
361         Console.ReadLine();
362      }
363   }
364}

The following C# example is the same as the previous C# example, except it uses .NET 3.0 SoapClient services instead of .NET 2.0 SforceService services.

1using System;
2using System.Collections.Generic;
3using System.Linq;
4using System.Text;
5using System.Threading.Tasks;
6
7using System.ServiceModel;
8using Walkthrough.sforce;
9
10namespace Walkthrough
11{
12    class QuickstartApiSample
13    {
14        private static SoapClient loginClient; // for login endpoint
15        private static SoapClient client; // for API endpoint
16        private static SessionHeader header;
17        private static EndpointAddress endpoint;
18
19        static void Main(string[] args)
20        {
21            QuickstartApiSample sample = new QuickstartApiSample();
22            sample.run();
23        }
24
25        public void run()
26        {
27            // Make a login call 
28            if (login())
29            {
30                // Do a describe global 
31                describeGlobalSample();
32
33                // Describe an account object 
34                describeSObjectsSample();
35
36                // Retrieve some data using a query 
37                querySample();
38
39                // Log out
40                logout();
41            }
42        }
43
44        private bool login()
45        {
46            Console.Write("Enter username: ");
47            string username = Console.ReadLine();
48            Console.Write("Enter password: ");
49            string password = Console.ReadLine();
50
51            // Create a SoapClient specifically for logging in
52            loginClient = new SoapClient();
53
54            // (combine pw and token if necessary)
55            LoginResult lr;
56            try
57            {
58                Console.WriteLine("\nLogging in...\n");
59                lr = loginClient.login(null, username, password);
60            }
61            catch (Exception e)
62            {
63                // Write the fault message to the console 
64                Console.WriteLine("An unexpected error has occurred: " + e.Message);
65
66                // Write the stack trace to the console 
67                Console.WriteLine(e.StackTrace);
68                return false;
69            }
70
71            // Check if the password has expired 
72            if (lr.passwordExpired)
73            {
74                Console.WriteLine("An error has occurred. Your password has expired.");
75                return false;
76            }
77
78            /** Once the client application has logged in successfully, it will use
79             * the results of the login call to reset the endpoint of the service
80             * to the virtual server instance that is servicing your organization
81             */
82
83            // On successful login, cache session info and API endpoint info
84            endpoint = new EndpointAddress(lr.serverUrl);
85
86            /** The sample client application now has a cached EndpointAddress
87            * that is pointing to the correct endpoint. Next, the sample client
88            * application sets a persistent SOAP header that contains the
89            * valid sessionId for our login credentials. To do this, the sample
90            * client application creates a new SessionHeader object. Add the session 
91            * ID returned from the login to the session header
92            */
93            header = new SessionHeader();
94            header.sessionId = lr.sessionId;
95
96            // Create and cache an API endpoint client
97            client = new SoapClient("Soap", endpoint);
98
99            printUserInfo(lr, lr.serverUrl);
100
101            // Return true to indicate that we are logged in, pointed  
102            // at the right URL and have our security token in place. 
103            return true;
104        }
105
106        private void printUserInfo(LoginResult lr, String authEP)
107        {
108            try
109            {
110                GetUserInfoResult userInfo = lr.userInfo;
111
112                Console.WriteLine("\nLogging in ...\n");
113                Console.WriteLine("UserID: " + userInfo.userId);
114                Console.WriteLine("User Full Name: " +
115                    userInfo.userFullName);
116                Console.WriteLine("User Email: " +
117                    userInfo.userEmail);
118                Console.WriteLine();
119                Console.WriteLine("SessionID: " +
120                    lr.sessionId);
121                Console.WriteLine("Auth End Point: " +
122                    authEP);
123                Console.WriteLine("Service End Point: " +
124                    lr.serverUrl);
125                Console.WriteLine();
126            }
127            catch (Exception e)
128            {
129                Console.WriteLine("An unexpected error has occurred: " + e.Message +
130                    " Stack trace: " + e.StackTrace);
131            }
132        }
133
134        private void logout()
135        {
136            try
137            {
138                client.logout(header);
139                Console.WriteLine("Logged out.");
140            }
141            catch (Exception e)
142            {
143                // Write the fault message to the console 
144                Console.WriteLine("An unexpected error has occurred: " + e.Message);
145
146                // Write the stack trace to the console 
147                Console.WriteLine(e.StackTrace);
148            }
149        }
150
151        /**
152        * To determine the objects that are available to the logged-in
153        * user, the sample client application executes a describeGlobal
154        * call, which returns all of the objects that are visible to
155        * the logged-in user. This call should not be made more than
156        * once per session, as the data returned from the call likely
157        * does not change frequently. The DescribeGlobalResult is
158        * simply echoed to the console.
159        */
160        private void describeGlobalSample()
161        {
162            try
163            {
164                // describeGlobal() returns an array of object results that  
165                // includes the object names that are available to the logged-in user. 
166                DescribeGlobalResult dgr = client.describeGlobal(
167                          header, // session header
168                          null // package version header
169                          );
170
171                Console.WriteLine("\nDescribe Global Results:\n");
172                // Loop through the array echoing the object names to the console             
173                for (int i = 0; i < dgr.sobjects.Length; i++)
174                {
175                    Console.WriteLine(dgr.sobjects[i].name);
176                }
177            }
178            catch (Exception e)
179            {
180                Console.WriteLine("An exception has occurred: " + e.Message +
181                    "\nStack trace: " + e.StackTrace);
182            }
183        }
184
185        /**
186        * The following method illustrates the type of metadata
187        * information that can be obtained for each object available
188        * to the user. The sample client application executes a
189        * describeSObject call on a given object and then echoes  
190        * the returned metadata information to the console. Object
191        * metadata information includes permissions, field types
192        * and length and available values for picklist fields
193        * and types for referenceTo fields.
194        */
195        private void describeSObjectsSample()
196        {
197            Console.Write("\nType the name of the object to " +
198                 "describe (try Account): ");
199            string objectType = Console.ReadLine();
200            try
201            {
202
203                // Call describeSObjects() passing in an array with one object type name 
204                DescribeSObjectResult[] dsrArray =
205                      client.describeSObjects(
206                        header, // session header
207                        null, // package version header
208                        null, // locale options
209                        new string[] { objectType } // object name array
210                        );
211
212                // Since we described only one sObject, we should have only
213                // one element in the DescribeSObjectResult array.
214                DescribeSObjectResult dsr = dsrArray[0];
215
216                // First, get some object properties                  
217                Console.WriteLine("\n\nObject Name: " + dsr.name);
218
219                if (dsr.custom) Console.WriteLine("Custom Object");
220                if (dsr.label != null) Console.WriteLine("Label: " + dsr.label);
221
222                // Get the permissions on the object 
223                if (dsr.createable) Console.WriteLine("Createable");
224                if (dsr.deletable) Console.WriteLine("Deleteable");
225                if (dsr.queryable) Console.WriteLine("Queryable");
226                if (dsr.replicateable) Console.WriteLine("Replicateable");
227                if (dsr.retrieveable) Console.WriteLine("Retrieveable");
228                if (dsr.searchable) Console.WriteLine("Searchable");
229                if (dsr.undeletable) Console.WriteLine("Undeleteable");
230                if (dsr.updateable) Console.WriteLine("Updateable");
231
232                Console.WriteLine("Number of fields: " + dsr.fields.Length);
233
234                // Now, retrieve metadata for each field
235                for (int i = 0; i < dsr.fields.Length; i++)
236                {
237                    // Get the field 
238                    Field field = dsr.fields[i];
239
240                    // Write some field properties
241                    Console.WriteLine("Field name: " + field.name);
242                    Console.WriteLine("\tField Label: " + field.label);
243
244                    // This next property indicates that this  
245                    // field is searched when using 
246                    // the name search group in SOSL 
247                    if (field.nameField)
248                        Console.WriteLine("\tThis is a name field.");
249
250                    if (field.restrictedPicklist)
251                        Console.WriteLine("This is a RESTRICTED picklist field.");
252
253                    Console.WriteLine("\tType is: " + field.type.ToString());
254
255                    if (field.length > 0)
256                        Console.WriteLine("\tLength: " + field.length);
257
258                    if (field.scale > 0)
259                        Console.WriteLine("\tScale: " + field.scale);
260
261                    if (field.precision > 0)
262                        Console.WriteLine("\tPrecision: " + field.precision);
263
264                    if (field.digits > 0)
265                        Console.WriteLine("\tDigits: " + field.digits);
266
267                    if (field.custom)
268                        Console.WriteLine("\tThis is a custom field.");
269
270                    // Write the permissions of this field
271                    if (field.nillable) Console.WriteLine("\tCan be nulled.");
272                    if (field.createable) Console.WriteLine("\tCreateable");
273                    if (field.filterable) Console.WriteLine("\tFilterable");
274                    if (field.updateable) Console.WriteLine("\tUpdateable");
275
276                    // If this is a picklist field, show the picklist values   
277                    if (field.type.Equals(fieldType.picklist))
278                    {
279                        Console.WriteLine("\tPicklist Values");
280                        for (int j = 0; j < field.picklistValues.Length; j++)
281                            Console.WriteLine("\t\t" + field.picklistValues[j].value);
282                    }
283
284                    // If this is a foreign key field (reference),     
285                    // show the values 
286                    if (field.type.Equals(fieldType.reference))
287                    {
288                        Console.WriteLine("\tCan reference these objects:");
289                        for (int j = 0; j < field.referenceTo.Length; j++)
290                            Console.WriteLine("\t\t" + field.referenceTo[j]);
291                    }
292                    Console.WriteLine("");
293                }
294            }
295            catch (Exception e)
296            {
297                Console.WriteLine("An exception has occurred: " + e.Message +
298                    "\nStack trace: " + e.StackTrace);
299            }
300            Console.WriteLine("Press ENTER to continue...");
301            Console.ReadLine();
302        }
303
304        private void querySample()
305        {
306            String soqlQuery = "SELECT FirstName, LastName FROM Contact";
307            try
308            {
309                QueryResult qr = client.query(
310                    header, // session header
311                    null, // query options
312                    null, // mru options
313                    null, // package version header
314                    soqlQuery // query string
315                    );
316
317                bool done = false;
318
319                if (qr.size > 0)
320                {
321                    Console.WriteLine("Logged-in user can see "
322                        + qr.records.Length + " contact records.");
323
324                    while (!done)
325                    {
326                        Console.WriteLine("");
327                        sObject[] records = qr.records;
328                        for (int i = 0; i < records.Length; i++)
329                        {
330                            Contact con = (Contact)records[i];
331                            string fName = con.FirstName;
332                            string lName = con.LastName;
333                            if (fName == null)
334                                Console.WriteLine("Contact " + (i + 1) + ": " + lName);
335                            else
336                                Console.WriteLine("Contact " + (i + 1) + ": " + fName
337                                   + " " + lName);
338                        }
339
340                        if (qr.done)
341                        {
342                            done = true;
343                        }
344                        else
345                        {
346                            qr = client.queryMore(
347                                    header, // session header
348                                    null, // query options
349                                    qr.queryLocator // query locator
350                                    );
351                        }
352                    }
353                }
354                else
355                {
356                   Console.WriteLine("No records found.");
357                }
358            }
359            catch (Exception ex)
360            {
361                Console.WriteLine("\nFailed to execute query succesfully," +
362                    "error message was: \n{0}", ex.Message);
363            }
364            Console.WriteLine("\nPress ENTER to continue...");
365            Console.ReadLine();
366        }
367    }
368}