Introduction
The Force.com platform tightly integrates with Microsoft .NET technologies via the Force.com SOAP API, which lets you, access and manipulates 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.
Need to have
To understand the article properly it is assumed that user is having good knowledge in .Net technology, C# language, basics on web services and salesforce (objects, tabs etc). Also this assumes that the user account used for doing operation on salesforce is having all required permissions to do so.
Background
To do any operation we need to have proper session login to Salesforce application and for which a Enterprise WSDL needs to be generated through which we will authenticate ourselves in Salesforce to do our operations. There are three types of WSDL types from which Enterprise WSDL will be of our use because this is the type which is mainly used when developing client applications for their organization.
Steps for Integration:
Step I (Generate the WSDL)
WSDLs are automatically generated and maintained by the platform. Whatever object we are creating in salesforce it will be automatically available to partner WSDL. Likewise if we are creating any webservice classes, its WSDL also be automatically available. To get it we can follow below steps:-
Go to the standard User Interface, get logged in and navigate as below, Setup >> Setup >> Develop >> API.
Choose the appropriate WSDL and download the file to a location accessible to your development environment. Or if appropriate WSDL expected is not there then do as below:- Login >> Setup >> Develop >> API >> Click on ‘Generate’ Now we have the WSDL URL to be used further.
Step II (Add reference to WSDL from .Net application)
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:
- Right click on project and choose ‘Add Service Reference’ option from menu.
- Add Service Reference dialog will be opened, click on ‘Advanced’ here.
- In the ‘Service Reference Settings’ dialog again click on ‘Add Web Reference’ button to proceed for adding Web Reference.
- In ‘Add Web Reference’ dialog enter the WSDL URL we collected previously and press Enter. Now it will prompt for salesforce account Username and Password. Give Username and Password and click on ‘Log in to Salesforce’ button.
- In next step give a proper name to the reference and click on ‘Add Reference’ button.
- Now we can see the web reference added by us in ‘Solution Explorer’ within our project’s ‘Web References’ folder.
Step III (Using the Web Reference)
To do any operation first of all we need an active session to the Salesforce API being established. For this we need three things as mentioned below:-
- Username: Username of the salesforce account through which you want to do all operations.
- Password: Password of the salesforce account through which you want to do all operations.
- Security Token: The Security Token is not required if the IP of the consumer is being added to the trusted IP list of the salesforce account otherwise Security Token is mandatory. For more details please check [here].
A security token is an automatically-generated key from Salesforce. For example, if a user’s password is spassword, and the security token is XXXXXXXXXX, then the user must enter spasswordXXXXXXXXXX to log in. Or, some client applications have a separate field for the security token.
NOTE : For access via the API or a client, users must add their security token (or time-based token if Two-Factor Authentication on API Logins is set on the user’s profile and the user has added a time-based token to his or her account) to the end of their password in order to log in.
Get the Security Token:
We can change the Security token via the Salesforce user interface. Changing password automatically sends a new security token to the email address on the user’s Salesforce record or user can do the same using Salesforce interface resetting of security password.
The security token is valid until a user does the below operations:-
- resets their security token directly
- changes their password
- Or has their password reset.
Steps to generate a new:
Click on the Username on right top corner of the page >> My Settings >> Personal >> Reset My Security Token. It will reset and create a new security token for you which can be used for authentication in .Net application by concatenating with login password.
Step IV (Authenticate and Create Salesforce API Session in .Net)
Declare required variables:
private string _username = “salesforce account username”;
private string _password = “salesforce account password”;
private const string _tokenID = "token id";
private string _sessionId;
private DateTime _nextLoginTime;
Private LoginResult _loginResult;
Private SforceService _sForceRef;
Check if session is valid:
private bool IsValidSession()
{
bool blnResult = false;
if (!string.IsNullOrEmpty(_sessionId) & _sessionId != null)
{
if (DateTime.Now > _nextLoginTime)
blnResult = false;
else
blnResult = true;
}
else
blnResult = false;
return blnResult;
}
}
Create Session if not valid:
i) Call the login method by passing username and password but password should be a combination of salesforce user account password and the security token. Ex:-
_loginResult = _sForceRef.login(_username, _password + _tokenID);
ii) Get session details from login result and store into the session variables. Ex:-
_sessionId = _loginResult.sessionId;
Session["SessionId"] = _loginResult.sessionId;
Session["ServerUrl"] = _loginResult.serverUrl;
Session["NextLoginTime"] = DateTime.Now;
iii) Establish proper force.com session to do any further operations
_sForceRef.Url = _loginResult.serverUrl;
_sForceRef.SessionHeaderValue = new SessionHeader();
_sForceRef.SessionHeaderValue.sessionId = _sessionId;
Check session validity before any operation:
Check if current session is valid and create if not valid. Ex:-
if (!IsValidSession())
isError = GetSessionDetails();
(NOTE: This can be checked on page load event handler)
Step V (Consuming Service to do CRUD Operations)
Like any API calls it will return a response for every call regardless of its success or failure status. So Salesforce API calls also retuns some response from which we can get the details of error or success. There are three kinds of array-based object through which API send response whether it is a success or failure. Those are like:-
1. SaveResult
2. DeleteResult
Above two will contain array of ids if the operation is success which are being affected by the operation or else it will contains array of error objects providing the details of the errors.
3. QueryResult : This will hold array of records as results on successful execution of the query string.
Fetch Data:
I have already created a custom object named as ‘Candidate’ in the salesforce account so below examples mainly based on all operations on the same object.
i) Instantiate QueryResult object like
QueryResult qr = null;
ii) Prepare query to be executed:
string strQuery = ("SELECT Id, Name, First_Name__c, Last_Name__c from Candidate__c where Name = '" + name + "'");
// here ‘name’ variable contains the name value for which record needs to be fetched
iii) Execute query and get result, Ex:
qr = _sForceRef.query(strQuery);
if (qr.size > 0)
{
Candidate__c p = (Candidate__c)qr.records[0];
}
Here p is the candidate object for the name supplied.
Create Record:
i) Create a new instance of the Candidate object,
Candidate__c newCand = new Candidate__c();
ii) Assign proper values to its various properties as below:
newCand.First_Name__c = "new first name";
newCand.Last_Name__c = "new last name";
iii) Call method for creation using the ‘SforceService’ object by passing the Candidate object we created in above step.
SaveResult[] saveResults = _sForceRef.create(new sObject[] { newCand });
It will return an array of ‘SaveResults’ which contains the success or failure status as well as saved record primary key id as below:
string result = string.Empty;
if (saveResults[0].success)
{
result = saveResults[0].id; }
else
{
result = saveResults[0].errors[0].message; }
Update Record:
i) Get the instance of the candidate object by its name like below:
Candidate__c c = GetCandidateByName(candidateName);
ii) If the candidate exists in the salesforce account with the supplied name then get the primary key id for the candidate into a new candidate object. Also assign the new values to the new candidate object which you want to modify:
Candidate__c existingCand = new Candidate__c();
existingCand.Id = c.Id;
existingCand.First_Name__c = "modified first name";
existingCand.Last_Name__c = "modified last name";
iii) Call the update method by supllying this new candidate object with new modified values. Now it returns ‘SaveResult’ array which contains success or failure message as well as the updated record primary key id. Ex-
SaveResult[] saveResults = _sForceRef.update(new SDFR.sObject[] { existingCand });
string result = string.Empty;
if (saveResults[0].success)
{
result = saveResults[0].id; }
else
{
result = saveResults[0].errors[0].message; }
Delete:
i) Get the candidate object by candidate name supplied from the user.
Candidate__c c = GetCandidateByName(candidateName);
ii) Get the unique primary key id of the candidate object and create a string array with the id, as delete method requires string id array to be passed to delete all the records for which ids are being passed through the id array.
String[] ids = new String[] { c.Id };
iii) Call the delete method on ‘SforceService’ object and it returns the DeleteResults array with delete success or failure status and id of the record if it is success.
DeleteResult[] deleteResults = _sForceRef.delete(ids);
iv) Now we need to check if the deletion operation is success or a failure.
If success get the id of the deleted item or else we can have the error message as below:-
string result = string.Empty;
if (deleteResults[0].success)
{
result = deleteResults[0].id;
} else {
result = deleteResults[0].errors[0].message;
}
Problems may arise during development and its solution
On using this web reference you may get error as below which I also got as well:-
Unable to generate a temporary class (result=1).
error CS0030: Cannot convert type 'Salesforce.Net.Web.SDF.ListViewRecordColumn[]' to 'Salesforce.Net.Web.SDF.ListViewRecordColumn'
To fix this issue we need to go to the dynamically generated file 'Reference.cs' file while adding our Web reference to the enterprise WSDL. Open the file and replace all '[][]' strings to only '[]'. To see further details you can refer to link [here].
Conclusion:
Refering this article you will definitely have an clear idea on how to integrate salesforce api into .net application so that we can access and do operations on salesforce objects through it.