Newer Version Available
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.
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:
- Prompts the user for their Salesforce username and password.
- 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.
- 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.
- 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.
- Calls query(), passing a simple query string ("SELECT FirstName, LastName FROM Contact"), and iterating through the returned QueryResult.
- 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:
- Prompts the user for their Salesforce username and password.
- 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.
- 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.
- 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.
- Calls query(), passing a simple query string ("SELECT FirstName, LastName FROM Contact"), and iterating through the returned QueryResult.
- 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