DEV Community

Rachel Soderberg
Rachel Soderberg

Posted on • Edited on

Integrating C# .NET and Salesforce's REST API

In my previous Salesforce series we learned how to perform authentication, login, run queries, and create, update, or delete records using the Salesforce SOAP API. In this new series we're going to work through similar tasks using the Salesforce REST API because not every technology stack, or development team, is willing and able to handle SOAP requests.

Today we're going to set up our application's connection to Salesforce, including the creation of our Connected App, and use our application to login through the Salesforce REST API. All of my code examples will be from a C# .NET Core application, but will work in .NET Framework as well, and my Salesforce examples will be using Lightning Experience (Spring 2020 release).

Connected App

The first step to integrating with the Salesforce REST API is creating a new Connected App within your Salesforce org. I recommend doing this in Test or Development first, before releasing your app into Production! This app will serve as the endpoint your application uses to authenticate with your Salesforce org and allows an admin to grant or restrict permissions for apps' access to data as well as users' access to external apps.

  1. Navigate to Setup > Apps > App Manager.
  2. Click "New Connected App".
  3. Fill in the required information on the New Connected App form using whatever Connected App Name you'd like, a real Contact Email, and a Callback URL. The Callback URL can be a dummy URL as we will be using the 'resource owner password grant' - in other words our application will authenticate with Salesforce using a legitimate user's Username and Password. Check Enable OAuth Settings and select "Access and manage your data (api)" under Selected OAuth Scopes. New Connected App
  4. Click Save and then click Continue. Take note of your Consumer Key and Consumer Secret. These cannot be revealed again and are essential for your application to access your org.
  5. As per the warning, don't use the app for several minutes after creation.

Authenticating From .NET

Next we need to create or modify our .NET application and create a few properties to store our login, authentication, and client info:

    public const string LoginEndpoint = "https://test.salesforce.com/services/oauth2/token";
    public const string ApiEndpoint = "/services/data/v36.0/"; //Use your org's version number

    private string Username { get; set; }
    private string Password { get; set; }
    private string Token { get; set; }
    private string ClientId { get; set; }
    private string ClientSecret { get; set; }
    public string AuthToken { get; set; }
    public string ServiceUrl { get; set; }

    static readonly HttpClient Client;

    static MyController()
    {
        Client = new HttpClient();
    }
Enter fullscreen mode Exit fullscreen mode

The above getters and setters contain confidential information. These should be stored using a secure method for retrieval during authentication.

We will build our authentication to the API using the HttpClient class for our asynchronous HTTP callouts, and FormUrlEncodedContent which is required by Salesforce. This can also be done synchronously if you choose by using the Result keyword on any async calls. If you are returned a bad request response, double check that you've used FormUrlEncodedContent correctly.

Note: If you run into a security error, add the TLS 1.1 or 1.2 protocols to your method or constructor and try to send the request again:
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11;

  HttpContent content = new FormUrlEncodedContent(new Dictionary<string, string>
      {
          {"grant_type", "password"},
          {"client_id", ClientId},
          {"client_secret", ClientSecret},
          {"username", Username},
          {"password", Password}
      });

  HttpResponseMessage message = Client.PostAsync(LoginEndpoint, content).Result;

  string response = message.Content.ReadAsStringAsync().Result;
  JObject obj = JObject.Parse(response);

  AuthToken = (string)obj["access_token"];
  ServiceUrl = (string)obj["instance_url"];
Enter fullscreen mode Exit fullscreen mode

Testing our method by printing the result of the response should return the following JSON object containing our authentication token as a string:

  "{
        \"access_token\":\"00D630000004mdS!AR0AQHhG_MsU_i5BqeqvimbRa.BP4Oanqn4v9UUedHDk_.BCP6p4dDPnnhZ7Y8nhtra1v2DWuPUOwt.IaDlj_XdnCYLgzIDd\",
        \"instance_url\":\"https://cs43.salesforce.com\",
        \"id\":\"https://test.salesforce.com/id/00D630000004mdSEAQ/00560000003gFPbAAM\",
        \"token_type\":\"Bearer\",
        \"issued_at\":\"1588270529868\",
        \"signature\":\"XFhjeOi/xxL+PoNW7kW1vhp1cgus9OT16fhoFEBEKfs=\"
  }"
  // These values have been modified for security
Enter fullscreen mode Exit fullscreen mode

If you run into an invalid_client_id error, go to Settings and view the Profile for the account you're using to log in. Verify that the new Connected App you've created is checked under Connected App Access.

The access_token and instance_url values are used to set our AuthToken and ServiceUrl respectively. We will access these values later when we perform queries, create new records, and update existing records.

In the next post of this series we will use our new authentication token to perform a query and retrieve an Account from our Salesforce org.


If you'd like to catch up with me on social media, come find me over on Twitter or LinkedIn and say hello!

Top comments (8)

Collapse
 
chadrs profile image
chad-rs

Did the post on performing the query ever happen? I couldn't find it.

Collapse
 
rachelsoderberg profile image
Rachel Soderberg
Collapse
 
rachelsoderberg profile image
Rachel Soderberg

Hey there! I was actually going to write and release that today, I've had a hectic couple of weeks and time got away from me :) Keep an eye out for that soon!

Collapse
 
areacode212 profile image
Prime Time Pauly G

Hey Rachel,

You actually can get to the Consumer Key & Consumer Secret again. From Salesforce Setup, you have to go to Apps->App Manager. That brings you to the "Lightning Experience App Manager". From that list, find the app, click the arrow on the right of the row, then click "View".

That said, I'm getting "invalid_grant" / "authentication failure" when I try to run this. I think the Connected App isn't set up correctly. I'm not seeing it in "Connected Apps OAuth Usage" or under my Profile in "OAuth Connected Apps". Is there anything else that needs to be set up for a new Connected App other than what you wrote in the article?

Collapse
 
areacode212 profile image
Prime Time Pauly G

Never mind, I was able to fix my issue by changing my login endpoint to the one that matches my actual sandbox (not test.salesforce.com, but xxxxx.my.salesforce.com)

Collapse
 
marilometa profile image
Marilo Meta

Hi,

I am trying to connect a WebAPI with my Salesforce Sandbox environment (with oauth2 protocol)
the logic I followed to do it is on your link: dev.to/rachelsoderberg/integrating...

I get a BadRequest as response on this part of code:

Collapse
 
joarath profile image
joarath

FYI: You need to append your API token to the password.

{"password", Password + ApiToken}

Collapse
 
ramyach profile image
Ramyach

Do you have source code GitHub for Salesforce integration using ASP.net.