This article is a continuation of the Salesforce REST API Services series. In this article we are operating under the assumption that you have already set up your Salesforce org and built an application that successfully authenticates with Salesforce and logs in. The steps in this tutorial will not work without the resulting AuthToken from your Salesforce org.
In today's tutorial we're going to perform a Query to our Salesforce org to return some information from an existing Account. This gives you the freedom to determine whether a specific Account exists so you can then programmatically perform actions on the Account from your .NET application instead of within Salesforce itself.
Performing a Query
I don't typically use these tutorials to cover specifics in programming style, but in this case I would like to briefly suggest creating a generic method specifically for performing queries. This set of code has the potential to be used numerous times within a single application, or even within a single function, and should not be rewritten each and every time. My code examples today will reflect this focus on smaller, more focused, software architecture.
The first step is to create a QueryRecord() method and pass in our HttpClient object and a queryMessage string. This message is identical to a SOQL query you would to perform this query in the Salesforce Developer Console. (This is exactly the same as the query string used for the SOAP API as well)
private string QueryRecord(HttpClient client, string queryMessage)
{
string restQuery = $"{ServiceUrl}{ApiEndpoint}query?q={queryMessage}";
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, restQuery);
request.Headers.Add("Authorization", "Bearer " + AuthToken);
request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
HttpResponseMessage response = client.SendAsync(request).Result;
return response.Content.ReadAsStringAsync().Result;
}
What I found most interesting about the RESTful service is that we are sending an HTTP Request to Salesforce for our query string using the known API Endpoint and the Service URL passed back from the authentication results instead of using a created binding object as seen in the SOAP API.
Next we add some information to the header, including the name of the header and its value from the AuthToken returned by our authentication. A response is sent back, which we can return the result of to our requesting method as a string.
public void GetAccount()
{
string companyName = "My Company";
string queryMessage = $"SELECT Id, Name, Phone, Type FROM Account WHERE Name = '{companyName}'";
JObject obj = JObject.Parse(QueryRecord(Client, queryMessage));
if ((string)obj["totalSize"] == "1")
{
// Only one record, use it
string accountId = (string)obj["records"][0]["Id"];
string accountPhone = (string)obj["records"][0]["Phone"];
}
if ((string)obj["totalSize"] == "0")
{
// No record, create an Account
}
else
{
// Multiple records, either filter further to determine correct Account or choose the first result
}
}
If you debug the program and expand the results when the queryMessage is parsed as a JObject, you'll see a fairly substantial JSON payload. At this point the most important piece is the value in the "totalSize" property, this is the number of records returned by the query. I like to use this to determine whether the results returned are what I expect (i.e.: there should only be one Account by a certain company's name), and whether it even exists at all in the org.
Once you've determined the number of results match what was expected, you can use the JObject as you would any other object using "records". This object works like an array so if there were more than one record returned you could iterate through them to retrieve a value from each. In our case though, we're simply getting the accountId and accountPhone from our first and only record and moving on. These values can be used to programmatically update your database, other Salesforce records, or an ERP.
The next installment of this series will cover updating our retrieved Account record with the customer's phone number, where ("totalSize" == "1") meaning one Account was retrieved by our query and no further decisions are necessary.
--
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 (1)
Awesome, that really helped me a lot