Integrating Force.com with Microsoft .NET

Abstract

The Force.com platform tightly integrates with Microsoft .NET technologies via the Force.com SOAP API, which lets you access and manipulate your data and functionality in the Force.com cloud. This functionality can be executed on any Microsoft.NET supported platform including but not limited to web applications running IIS, Windows desktop or server applications, SharePoint services, and SQL Server programmability.

This article provides details on the various options to integrate the Force.com platform with Microsoft .NET. After reading this article, you will have a foundation of methodologies, best practices and code samples to leverage the Force.com SOAP API across any Microsoft .NET platform.

Benefits of Integrating the Force.com Platform with Microsoft .NET

Force.com can be tightly integrated with any Microsoft .NET based application through the Force.com SOAP Application Programming Interface (API). By exposing, consuming and editing an organization's Force.com data through the API, Microsoft .NET developers can leverage existing toolsets and programming language knowledge, enabling them to develop a Force.com integrated application rapidly and efficiently.

While Visual Basic .NET and C# are the most widely used .NET programming languages, an application that uses the Force.com SOAP API can be written in any .NET compatible programming language. Microsoft's and salesforce.com's adherence to industry-accepted web service standards allows developers to use familiar coding methodologies and techniques with little additional training. Developers can also save time in developing their application by leveraging the existing business logic and security model provided out of the box through the use of the API.

There are of course many forms of integration. For example, you may choose to build and run your Microsoft apps on an intranet, and then bridge to a Force.com application using some kind of single sign on (SSO) methodology, such as SAML. This can easily be done, and you can find the details in Single Sign-On with SAML on Force.com. This article focuses primarily on an integration based around the data within a Force.com application - something that will allow you to react to changes to that data, or insert or remove on Force.com from your local Microsoft application.

Methodologies and Delivery Platforms

As with other code bases written in .NET, an integrated Force.com application can be tailored to run on any .NET support platform. The Microsoft .NET Framework is included with all major Microsoft operating systems, desktop and server, as well as Microsoft's 3 major application platforms: SQL Server, Internet Information Services, and SharePoint Services. Thus, the Force.com API can be accessed and consumed across any of the aforementioned platforms with little to no additional development effort.

Generating and Consuming WSDLs: The Basics of Integration

In order for a .NET application to integrate with Force.com, a reference to the SOAP API must be added to the application within Visual Studio. This reference is established through the use of a WSDL file generated from the Force.com platform. A WSDL file is an XML file that describes how a SOAP-based web service functions, how an application can communicate with the web service, and the operations allowed to be conducted within the SOAP API.

In other words, the WSDL provides a description of the bridge between your Microsoft application, and a Force.com application running in a Force.com environment (or organization).

WSDL Types

Force.com offers several types of WSDLs to consume, depending on the requirements of the application being developed and the audience for whom the application is developed. Regardless of the WSDL used, the Force.com API enforces several concepts across all WSDL types consistent with the World Wide Web Consortium's (W3C) accepted standards including, but not limited to: how to communicate with the web service, how to authenticate with the web service, and what operations are allowed with the web service.

The Force.com platform offers many WSDL types for API access, with the primary WSDLs being the Enterprise, Partner and Apex Class WSDLs. Choosing the correct WSDL will depend on the type of application being developed.

  • Enterprise WSDL - This API is for users who are developing client applications for their organization. The enterprise WSDL file is a strongly typed representation of your organization's data. It provides information about your schema, data types, and fields to your development environment, allowing for a tighter integration between it and the Force.com Web service. This is ideal if you're writing an application for your own Force.com application and data. When using this type of WSDL you will need to re-import and compile your integration if you want your integration to be aware of data schema changes.
  • Partner WSDL - This API is for salesforce.com partners who are developing client applications for multiple organizations. As a loosely typed representation of the object model, the partner WSDL can be used to access data within any organization. This is ideal if you want to write something that will work against many different applications across many different partners without the need to be aware of the exact data schema implemented by the customer.
  • Apex WSDL - This API is used with custom Apex classes created on the Force.com platform. The API allows access to the properties and operations of an Apex class similar to objects exposed in the Partner and Enterprise APIs.

The important point here is if you want to create an application that can run against any customer application running on Force.com, then you probably want to use the Partner WSDL. For example, a generic data tool may have this requirement. However, if you have more control over the application you want to integrate with, and understand how often its data model changes, then the Enterprise WSDL may be more beneficial - the strongly typed representation is very useful during coding.

Generating a WSDL

All of these WSDLs are automatically generated and maintained by the platform. For example, if you create a new object it will be automatically be made available within the partner WSDL. Likewise, if you create a new Apex class that functions as a web service, its WSDL will be automatically made available.

WSDL files are retrieved via the standard user interface in an organization by logging in and navigating to Setup > App Setup > Develop > API. Choose the appropriate WSDL and download the file to a location accessible to your development environment.

Adding a Web Service Reference to an Application

The steps to add a web reference will vary, depending on the edition of Visual Studio used as well as the .NET Framework for which the application is developed. Visual Studio 2008 and newer now reference 'Add Service Reference' to projects and have deprecated the 'Add Web Reference' term. Regardless of terminology or versions, the steps to add a reference to your WSDL file are in essence the same across all versions of Visual Studio:

1. Open the add reference dialog box via the 'Add Service Reference' or 'Add Web Reference' command from the Project menu.

2. Provide location of WSDL file in order to create the reference. Locations can take multiple forms including HTTP address. In this case, the location will point to a location on your local hard drive or network share.

Net addwebref.png

3. Establish name of reference to be used in your application. This is referred to as either the Web reference name or Namespace. Regardless of terminology, this name will become the established namespace for all references to objects, properties and methods enclosed in the WSDL file.

Net addserviceref.png

4. Confirm the reference has been added by viewing the reference in the Solution Explorer in Visual Studio.

Net solutionexplorer.png

That's it! You're now ready to start using the reference and interacting with apps on Force.com.

Using the Force.com Reference

Now that you have your reference, you need to authenticate with the Force.com servers. This determines which organization you get access to, and which data. After that, you'll be in a position to add or query data. The following sections look at this process in a lot more detail.

Authentication and Other Security Considerations

Before using any functionality or accessing any data through the Force.com platform, a valid username and password must be passed to the API in order to authenticate and establish a secure session with the API. Only then will the .NET application be allowed to interact with the Force.com API. Consideration should be given during the design of your application as to how the application authenticates against the API.

All security and subsequent operations can be conducted under the context of a single service account, established solely for the purpose of API access for you application. Alternatively, individual users of the .NET application can conduct operations under the context of their individual Force.com user account. Either option will have significant impacts on the architecture of your application and is beyond the scope of this document.

Regardless of the authentication method used, there are security considerations to keep in mind when developing an application:

  • Session State: All operations, regardless of the chosen authentication method, must be conducted with a valid Force.com session established. Fortunately for .NET developers, all of the necessary legwork is done for you when a Force.com API service is first instantiated. A developer just simply needs to capture the pertinent values returned from the Force.com API and consume them appropriately in her application.
  • Object and Field level permissions: The Force.com SOAP API utilizes the same security framework on which other Force.com applications run. This universal architecture allows a .NET developer to establish the appropriate permissions for both objects (standard and custom) as well as individual fields within the Force.com platform. These permissions will trickle down to a .NET application and prevent any unauthorized operation or permit an allowed operation without any additional programming.
  • CRUD Operations: Like object and field level permissions, the Force.com security framework controls what CRUD (Create, Read, Update, Delete) operations are permitted for a given object type. Once again, the heavy lifting has already been handled within the Force.com platform, thus removing the need for additional programming.

Let's walk through the code of a basic app to make this more concrete.

Walkthrough: Authenticating and Creating a Session

Integrating .NET with Force.com can be accomplished following a few simple steps. All samples are written in C#.

1. Capture a user name and password: These values can be hardcoded as part of your application's .config files, stored in a database for retrieval, or passed to the API via values collected from the application user. In this example, the username and password are simply hard coded as string variables within the application.

string userName;
string password;
userName = "username@domain.com";
password = "somecomplexpassword";

2. Login to the Force.com API: Once the username and password values are established, they are passed to the API to determine if they are valid. As part of this validation, a binding to the API is established by instantiating an SforceService object. Once the binding is established, the result of the login attempt is returned in the form of a LoginResult object. Best practices also dictate this login attempt be wrapped in a try catch block to allow for graceful handling of any exceptions that may be thrown as part of the login process.

SforceService SfdcBinding = null;
LoginResult CurrentLoginResult = null;
SfdcBinding = new SforceService();
try {
   CurrentLoginResult = SfdcBinding.login(userName, password);
}
catch (System.Web.Services.Protocols.SoapException e) {
   // This is likley to be caused by bad username or password
   SfdcBinding = null;
   throw (e);
}
catch (Exception e) {
   // This is something else, probably comminication
   SfdcBinding = null;
   throw (e);
}

3. Establish the Session: Once a successful login has been executed, it is necessary to establish a valid Force.com API session by setting the endpoint URL for your binding object to communicate with as well as set any required values to create a valid session header.

//Change the binding to the new endpoint
SfdcBinding.Url = CurrentLoginResult.serverUrl;

//Create a new session header object and set the session id to that returned by the login
SfdcBinding.SessionHeaderValue = new SessionHeader();
SfdcBinding.SessionHeaderValue.sessionId = CurrentLoginResult.sessionId;

That's it! You have just successfully logged in to the Force.com API and created a valid session to conduct further operations on the Force.com platform. The SfdcBinding variable now contains the end point URL where further web service interactions will take place, as well as the session. The following code will use this to retrieve and create data on Force.com from .NET.

Walkthrough: Viewing and Consuming Force.com Data

Now that a valid session has been established, Force.com data can be queried from the platform and consumed in your .NET application. Queries are executed against the Force.com API using SOQL (Salesforce.com Object Query Language).

SOQL is similar to SQL and can be used in a similar manner to specify precisely the data your .NET application requires to consume. Results from the SOQL sent to the API are stored in a QueryResult object, which in essence is simply an array of records returned from the API that can be handled similarly to a dataset or data reader.

1. Instantiate a QueryResult to hold the results: There are numerous options that can be set via the QueryOptions object. These options are beyond the scope of this document but can be found in the Force.com Web Services API Developer's Guide.

QueryResult queryResult = null;

2. Construct the Query: Queries can be built on the fly based on other interactions within your .NET application or they can be predefined if the query is executing in a more controlled, predictable piece of code. If the developer has any level of familiarity with SQL, one will be able to construct SOQL queries with ease. In this example, the Force.com API will be queried for a lead record with an email address of john.smith@salesforce.com. Our application requires the lead record's first name, last name and phone number.

String SOQL = "";

SOQL = "select FirstName, LastName, Phone from Lead where email = 'john.smith@salesforce.com'";

3. Execute the Query: Once the QueryResult object and SOQL query string have been established, it's time to execute the query against the API.

queryResult = SfdcBinding.query(SOQL);

4. Consume the Results: Now that the query has been executed, we must check to see if any results were returned. If results were returned from the API, our application can now consume the records, otherwise the lack of records returned can be handled gracefully to provide meaningful feedback to the calling application. In this case, we are going to assume that a single record was returned by our query.

if (queryResult.size > 0) {
  //put some code in here to handle the records being returned
  int i = 0;
  Lead lead = (Lead)queryResult.records[i];
  string firstName = lead.FirstName;
  string lastName = lead.LastName;
  string businessPhone = lead.Phone;
} else {
  //put some code in here to handle no records being returned
  string message = "No records returned.";
}

You've just consumed your first piece of Force.com data in your .NET application! Note how the the result is typecast to a Lead object - a result of this example using the Enterprise WSDL which is strongly typed. If it used the Partner WSDL, the code will be considerably more verbose. In particular, it would use SObjectResult type that can be used to represent any concrete type, and you have to use generic field methods (passing in as a parameter the name of the field on which you want to operate) to access or manipulate field data.

Walkthrough: Creating Force.com Data

The Force.com API supports all CRUD operations. We've just covered a walkthrough for ‘R', reading data from the API. This walkthrough covers the basics or creating data on the Force.com platform using the create() call as well as introduces the SaveResult object.

1. Instantiate the Object Being Created: Before we can execute a create() against the API, we must establish the type of object being created. In this case, we will create a new lead.

Lead sfdcLead = new Lead();

2. Establish Field Values and Object Properties: Like any .NET variable, there are numerous ways to establish the values to pass to the create() call. In this case, the values are simply hard coded as variable values. However, a more practical use would include capturing the values from a user via a web form or desktop application. Once the values have been established, the object properties must be set before the object is created. Your application should have its own layer of validation and business logic to ensure the values being set are validated.

string firstName = "Jane";
string lastName = "Doe";
string email = "jandoe@salesforce.com";
string companyName = "Salesforce.com";

sfdcLead.FirstName = firstName;
sfdcLead.LastName = lastName;
sfdcLead.Email = email;
sfdcLead.Company = companyName;

3. Execute Create Call and Capture Save Results: Now that the object has been instantiated and properties have been set, we can now execute the create() call against the API. The results of the create call are stored in a SaveResult object to allow your application to gracefully handle the results, regardless of success or failure. Note that both the SaveResult and subject objects are arrays and are thus built to handle multiple records simultaneously. In this case, we are operating on a single record only.

SaveResult[] saveResults = SfdcBinding.create(new sObject[] { sfdcLead });

4. Working with the Results: The create call will obviously result in success or failure. Successful create calls will return the ID value of the resultant record created. Fortunately, the API is built to allow us to handle both scenarios within our application.

if (saveResults[0].success) {
  string Id = "";
  Id = saveResults[0].id;
} else {
  string result = "";
  result = saveResults[0].errors[0].message;
}

Congratulations! You have just successfully created a new record on the Force.com platform from a .NET application.

Walkthrough: Updating Force.com Data

Now that we have an existing record, subsequent updates can be made to that record through your application. In order for the Force.com platform to execute a successful update call, the ID value of the object must be provided.

1. Create the Object to Update: Like a create call, an update call can operate on a single record or multiple records. In this case, we will operate on a single record.

Lead updateLead = new Lead();

2. Establish Values: Once the object to update has been created, the values to be updated must be established. The ID of the object must be set in order to execute the update so the API know which record to update. Failure to provide the ID or providing an invalid ID will result in an error.

updateLead.Id = Id;
string newEmailAddress = "janesmith@salesforce.com";
string newLastName = "Smith";
updateLead.Email = newEmailAddress;
updateLead.LastName = newLastName;

3. Execute the Update: Once the values we wish to change have been established, the update is executed and results are captured in a SaveResult object.

SaveResult[] saveResults = SfdcBinding.update(new sObject[] { updateLead });

4. Working with the Results: Like the results of a create call, the results of an update will contain an array of results equal to the array size of records in the update call. The results can be utilized in the same manner as a create call results in order to allow your application to handle both a successful and failed update.

string result = "";
if (saveResults[0].success) {
  result = "The update of Lead ID " + saveResults[0].id + " was succesful";
} else {
  result = "There was an error updating the Lead. The error returned was " + saveResults[0].errors[0].message;
}

As is evident in the update and create calls, the Force.com API establishes a very consistent method of interacting with your application, allowing for rapid development and reuse of code.

Walkthrough: Deleting Force.com Data

Deleting data on the Force.com API is very simple. The delete operation of your SforceService binding accepts an array of ID values as a parameter. Instead of populating a SaveResult object, the Force.com API populates the results of a delete call in a DeleteResult object.

1. Establish the IDs: A string array must be established containing the IDs of the records to be deleted.

String[] ids = new String[] { Id };

2. Execute Delete Call: Once the array of IDs has been established, the array is passed as a parameter to the delete call of the SforceService object established.

DeleteResult[] deleteResults = SfdcBinding.delete(ids);
DeleteResult deleteResult = deleteResults[0];

3. Capture Delete Results: Similar to a create and update call, the results of the operation are stored in an array object, in this case a DeleteResult. In this example, the array will have a single value as we are only passing a single ID value to delete.

if (deleteResult.success) {
  result = "Record ID " + deleteResult.id + " deleted succesfully.";
}
else {
  result = "Delete failed";
} 

Force.com API Response Handling

Like other applications, calls to the Force.com API will result in either success or failure. Application exceptions when using the Force.com API are handled in the same manner as a typical exception in any other .NET application and are managed through try/catch/finally blocks.

Successful calls and calls resulting in an error response from the API typically populate an array-based object. Basic responses from the API are captured in the following array objects:

  • SaveResult: A successful create or update call will contain an array of ID's of sObjects created or saved. If an operation is not successful, the SaveResult will be populated with an array of Error objects providing the details of the error. There are a vast amount of error messages/codes returned from the API which are covered in the SOAP API Developer's Guide.
  • DeleteResult: Similar to a SaveResult, a DeleteResult will contain an array of ID's or Errors, depending on the results of the detele call.
  • QueryResult: After a successful query, an array of records will be returned to your application containing the results.

All of the above result objects are handled in the same manner as an Array object in .NET. The results objects can be looped through using any standard .NET programming technique. These techniques are beyond the scope of this document.

Other Ways to Integrate

There are several other integration methodologies possible with the Force.com API. For completeness, those API's are highlighted here to further show what is possible with the Force.com platform and Microsoft .NET.

  • Metadata API - This API allows your application to manage the metadata of your organization's Force.com instance. This API is intended for managing customizations and for building tools that can manage the metadata model, not the data itself.
  • Bulk loader API - The bulk API allows you to load large amounts of data quickly and easily onto the Force.com platform. Accessing the API from Visual Studio is accomplished in the same manner as the SOAP API WSDL's. Developers can choose between use of the REST-based API or SOAP-based API, depending on the number of records used in your application.

As indicated in the introduction, you could also integrate in terms of a single sign on solution.

Summary

Establishing an integration between a .NET application and an application running on Force.com is not challenging. It requires a little planning around what type of integration is going to be made, and as a result which web service endpoint and WSDL will be invoked. After that, the actual coding of an integration is trivial - it's a matter of importing the WSDL, authenticating against the servers, and then simply writing against the API to add, remove, update or delete data.

References

  • The Integration resource page on Developer Force points to many additional resources on this topic.
  • See the Documentation page, and in particular the Force.com SOAP API Developer's Guide.

About the Author

Steve Baines has over 15 years of industry experience and currently manages his own consulting practice, specializing in Marketing Operations and Technology, application development and systems integration.