October 30, 2014
Hot Topics:
RSS RSS feed Download our iPhone app

Salesforce Integration with .NET Custom Web Services

  • March 27, 2011
  • By Darren Terrell
  • Send Email »
  • More Articles »

Introduction to Salesforce Integration

There are a number of ways to integrate Salesforce with .Net. In the first article, Salesforce Integration with .Net – Web Services SOAP API, we reviewed the API built into the Enterprise WSDL. This API allows us to query and manipulate Salesforce data from inside a .Net environment. While this is very beneficial for an enterprise, so is connecting to the business logic in the cloud. Salesforce comes with a plethora of functionality built into the platform. In addition, many organizations have developers actively writing Apex code. This functionality can be used via custom web services written in Apex. The focus of this article will be concentrated on calling custom web services written in Apex, from a Microsoft .Net environment, through authenticated and unauthenticated methods.

Building the Apex Web Services

The first step of the process is to construct an Apex Web Service that will be consumed by our ASP.Net web application. This will involve using code from the first article, Salesforce Integration with .Net – Web Services SOAP API, as a starting point. We will be able to reuse the connection elements implemented in that solution.

To construct the web service, you can use either Eclipse, with the Salesforce plug-in, or the Salesforce built-in web editor. For this example, I’ll use Eclipse since it has more features like intelliSense and keyword color coding. Conceptually, this will be similar to creating web services in ASP.Net. First, you will create your service class and then follow up by adding web methods to it. Follow the steps below to setup your Apex web service:

  • Create a new Apex class in Eclipse. Refer to the Apex Web Service class ContactManager.cls listed below to see the class in its entirety.

     

  • For us to be able to see this class from the outside world, we need to change the access modifier on the class definition to global. Therefore, replace the default public modifier with global as depicted below: global with sharing class ContactManager {

     

  • Next, we need to create a web method on our service to list all of the contacts that have an email address. First of all, the method will need to be marked as static. The access modifier for the method must be public and prefixed with the webservice keyword. This keyword signifies to Salesforce to include this method in the custom generated WSDL. webservice public static List<EmailRecipient> GetAllContactEmails() {

     

  • The return for the GetAllContactEmails() method is a inner class called EmailRecipient. Apex web methods can accept inner classes or primitive data types as parameters and also return them. Primitive data types are the built-in type such as string, integer, and id. Inner classes need the global access modifier and have their variables prefixed with the webservice keyword. Just like the service class, this keyword is used during the generation of the custom WSDL. Inner classes are simply used to transport the data. So, the constructors will not be replicated in the WDSL for the class.
    ContactManager.cls Apex Class
    global with sharing class ContactManager {

    global class EmailRecipient {
    webservice id ContactID;
    webservice string FullName;
    webservice string FirstName;
    webservice string LastName;
    webservice string EmailAddress;

    private EmailRecipient() {

    }

    public EmailRecipient(id contactID, string firstName,
    string lastName, string fullName, string emailAddress) {

    this.ContactID = contactID;
    this.FirstName = firstName;
    this.LastName = lastName;
    this.FullName = fullName;
    this.EmailAddress = emailAddress;
    }
    }

    webservice public static List<EmailRecipient> GetAllContactEmails() {
    List<EmailRecipient> recipients = new List<EmailRecipient>();

    for (Contact c: [SELECT c.ID, c.Email, c.FirstName, c.LastName, c.Name
    FROM Contact c
    WHERE Email <> '']) {
    recipients.Add(
    new EmailRecipient(c.ID, c.FirstName, c.LastName, c.Name, c.Email));
    }

    return recipients;
    }

    webservice public static EmailRecipient GetEmailRecipient(Id contactID) {
    Contact c = [SELECT c.ID, c.Email, c.FirstName, c.LastName, c.Name
        FROM Contact c
                        WHERE c.ID = :contactID];
                              
           return new EmailRecipient(c.ID, c.FirstName, c.LastName, c.Name, c.Email);
    }

    webservice public static void UpdateEmail(Id contactID, string emailAddress) {
    Contact contact = [SELECT ID, Email FROM Contact WHERE ID = :contactID];
    contact.Email = emailAddress;

    update(contact);
    }
    }
  • To generate the WSDL, log into Salesforce and traverse to Setup > Develop > Apex Classes. Click on the WSDL link next to the ContactManager class to download the WSDL as illustrated in Figure 1.

Figure 1
Figure 1  - Class List

Now that we have the ContactManager WSDL download, let’s take a look at how to consume it in an ASP.Net application.

Consuming Custom Web Services

The first things we need to do are save the WSDL in a project folder and create a web reference. We covered this in the previous article Salesforce Integration with .Net – Web Services SOAP API. After these are in place, we interact with the custom web service much like we did with the Enterprise WSDL. However, the custom web service will be accessed using the CustomManagerService. As illustrated in the CustomWS controller below, we need to authenticate our connection with Salesforce and grab the SessionID. Notice, we do not need to grab the URL from the login like in the Web Services SOAP API. The URL that will be called is located at the bottom of the ContactManager.wsdl (see below).

ContactManager.wsdl Excerpt
<soap:address location="https://na9-api.salesforce.com/services/Soap/class/ContactManager"/>

CustomWS.cs Controller Excerpt
public ActionResult List()
{
using (ContactManagerService proxy = new ContactManagerService())
{
ForceConnection connection = new ForceConnection("SalesforceLogin");
proxy.SessionHeaderValue = new SessionHeader() { sessionId = connection.SessionID };

EmailRecipient[] recipients = proxy.GetAllContactEmails();

return View(recipients);
}
}

After the ContactManagerService class is instantiated, a call to GetAllContactEmails method grabs all of the EmailRecipients. The method definition is from the ContactManager Apex class we previously created. Furthermore, the EmailRecipients inner class is represented as the return array. Once the proxy method is executed, a web service call is made to Salesforce executing the logic contained within. Once the recipients are retrieved, they are passed as ViewData to the List view. As shown here, the data is displayed in our page. The sample code with this article contains some further examples that are not covered directly in this article.

List.aspx View Excerpt
<html>
<head runat="server">
   <title>List Contacts  (Custom Web Service)</title>
</head>
<body>
   <div>
       <p><a href="/">Return Home</a></p>
   </div>
   <div>
       <p>Contacts</p>
       <ul style="list-style-type: none;">
   <%
       foreach (NetToSalesforce.CustomWS.EmailRecipient c in Model)
       {
           Response.Write(
               String.Format("<li><a href='/customws/edit/{0}'>{1}</a> {2} </li>",
                   c.ContactID,
                   c.FullName,
                   c.EmailAddress));
       }
   %>
       </ul>
   </div>
</body>
</html>

In this example, we were required to authenticate before being able to access the web service. However, this can also be achieved in an approach that allows anonymous interaction.

Unauthenticated Access

Consuming custom web services without any authentication requires some additional setup in both Salesforce and the ASP.Net project. By doing this, your business logic is open to anyone to use. Therefore, you can share functionality and data with business partners or other departments within your organization without having them maintain login information. However, be wary that this could be a potential security issue depending on what aspects of Salesforce you expose to the public.

Salesforce Setup

The first step in Salesforce is to setup a site. Sites are used in Salesforce to allow public access for integrating the platform directly into an organization’s applications. Multiple sites can be defined to allow you to define different access levels, pages, and templates. This permits organizations to use the Salesforce platform to build public web applications that can cater to the security and data needs of the audience.

To begin creating a new site in Salesforce, click on the "New" button. The default web address will be used when calling the site from your .Net application. Enter a label and name for the site. Make sure to mark the site active and set the active site home page. The home page will be displayed when someone directly navigates to the default web address. I chose the "Unauthorized" page since only web service access is desired and I do not want to use the page to display information.

Figure 2 
Figure 2  - New Site Window

After saving the new site, click on the "Public Access Settings" button. When the settings page opens navigate to the "Standard Objects Permissions" section and enable read access for Contacts. This is shown in Figure 3.

Figure 3 
Figure 3 - Standard Object Permissions

After setting the object permission, scroll down to the "Enable Apex Class Access" section and add the ContactManager class where our web service methods are defined. You can see an example of this in Figure 4. Also, in that screenshot you will notice the "Login IP Ranges" section. This area allows for the restriction to the site limited to only specified addresses. This enables a degree of security for the unauthenticated web service.

Figure 4 
Figure 4 - IP Ranges / Enable Apex Class Access

We can proceed to the .Net application setup now that Salesforce is configured to allow anonymous access to the ContactManager web service methods.

ASP.Net Setup

The ASP.Net application will only need a couple of tweaks. In the CustomWS controller, we need to remove the line establishing the connection to Salesforce. Also, the proxy URL needs to be updated to map to the site we created in Salesforce. The base of the URL is listed in Salesforce under the site. This will need "/services/SOAP/class/[classname]" appended on. An example of these changes is listed below.

CustomWS.cs Controller Excerpt

public ActionResult UnauthList()
{
using (ContactManagerService proxy = new ContactManagerService())
{
proxy.Url = "https://[your name]-developer-edition.na7.force.com/services/Soap/class/ContactManager";

EmailRecipient[] recipients = proxy.GetAllContactEmails();

return View(recipients);
}
}

The final change that is needed is to add the following setting to the web.config for the ASP.Net web application. This could also be added programmatically in the application. If this was not added, then the following error would be thrown: "The request failed with HTTP status 417: Expectation failed."

Web.config Excerpt
<system.net>
 <settings>
   <servicePointManager expect100Continue="false" />
 </settings>
</system.net>

Conclusion

In this article we reviewed how to create custom Apex web services in Salesforce. Business logic, algorithms, and data can be exposed by adding these services in Salesforce. They can be consumed by .Net simply by establishing a web reference. Depending on how the service is created, authentication may not be required. Having access to custom web services should lower development time, increase cohesion, and enable integration to an existing enterprise infrastructure.


Tags: .NET, Web services, Salesforce, tutorial, Salesforce integration

Originally published on http://www.developer.com.


Comment and Contribute

 


(Maximum characters: 1200). You have characters left.

 

 


Sitemap | Contact Us

Rocket Fuel