Newer Version Available

This content describes an older version of this product. View Latest

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.

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

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 Force.com 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.

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

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.

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