Saturday, November 17, 2012

Windows 8 + Salesforce.com Part 2

This is the second part of a series of posts on how to create a Windows 8 WinRT application that uses the Salesforce REST API. In the first part I showed all the code needed to authenticate to Salesforce. In this post I will show how to to retrieve data from Salesforce. In part 3 we will pull all the pieces together a display the data.
First thing we need is an object model to hold the data we retrieve from Salesforce. For the purposes of this application we will read a list of Accounts. Let’s start with a class to hold a single Account:

public class sfdcAccount
{       
    public sfdcAttributes Attributes { get; set; }

    public string Id { get; set; }
    public string Name { get; set; }
    public string AccountNumber { get; set; }
    public string Type { get; set; }
    public string Phone { get; set; }
    public string WebSite { get; set; }
    public string Industry {get; set;}
    public string BillingStreet { get; set; }
    public string BillingCity { get; set; }
    public string BillingState { get; set; }
    public string BillingPostalCode { get; set; } 
    public string CustomerPriority__c { get; set; }
 }

The first property is of type sfdcAttributes and will be used to hold meta-data about the record, we will look as this class next. The rest of the properties are a selection of fields from the Account record. There are more fields then this in Salesforce but this is a good group to work with. Here is the sfdcAttributes class that holds the type of the record and it’s unique URL. This can be used with any Salesforce object, not just the Account.

public class sfdcAttributes
{
    public string Type { get; set; }
    public string Url { get; set; }
}

Finally, we need a class to hold the meta data that is returned when we query for a group of records.

public class sfdcCollection<T>
{
    public bool done { get; set; }
    public int totalSize { get; set; }
    public string nextRecordsUrl { get; set; }
    public ObservableCollection<T> records { get; set; }
}

I made this a generic class so that it can be used for a collection of any Salesforce object, for example sfdcCollection<sfdcAccount> for a collection of accounts. The records property will hold the collection of sfdcAccounts. In the Windows forms application I made this a List<T> but to facilitate XAML data binding I have made it an ObservableCollection<T> which allows the binding system to detect changes to the collection. You will need to include the System.Collections.ObjectModel namespace to use the ObservableCollection.

In the last post we created a class called sfdcLibrary to hold all our Salesforce related code. We will add the following property and constructor to this class.

public string VersionUrl { get; set; }

public sfdcLibrary()
{
    VersionUrl = "/services/data/v26.0";
}

The Salesforce REST supports multiple versions of the API, so whenever you make a call to the API you must use the URL for the appropriate version. This variable will allow us to specify the version we want to use in one place. In this case we will hard code it to v26.0 of the API.

Now that we have an object model to hold the data we want to display we need some code to read it from Salesforce.


public async Task<sfdcCollection<sfdcAccount>> ReadAccounts()
{
    var query = accessToken.instance_url + VersionUrl + "/query?q=SELECT id,accountNumber,name,BillingStreet,BillingCity,BillingState,BillingPostalCode,CustomerPriority__c,Type,Phone,WebSite,Industry from account";

    var resp = await HttpGet(query);

    sfdcCollection<sfdcAccount> accts = null;

    if (resp.StatusCode == System.Net.HttpStatusCode.OK)
    {
         accts = Deserialize<sfdcCollection<sfdcAccount>>(await resp.Content.ReadAsStringAsync());
    }
    return accts;
}

This function will read all the Account records from your Salesforce instance, and return them in an sfdcCollection of sfdcAccounts (the Task<> is needed  because this is an async function). Reading all the records isn’t really practical in a real world application since it might return a very large number of records, but it is ok for the purposes of this demonstration.

In the first line of the function we build the URI to query for the Account fields we want. The URI starts with the instance URL, we then appends the version URL to this and finally the SOQL query.  The second line uses the HttpGet function to get the results of the query in the form of an HttpResponseMessage object, we will look at HttpGet in a second. Finally we check the HTTP status from the request and if it was successful  we use the Deserialize function which I showed in the last post to turn the JSON response into a object model we can work with.

The final function we need to look at is HttpGet.

public async Task<HttpResponseMessage> HttpGet(string uri)
{
    System.Net.Http.HttpClient client = new System.Net.Http.HttpClient();
    client.DefaultRequestHeaders.Add("Authorization", "OAuth " + accessToken.access_token);

    return await client.GetAsync(uri);
}

This works pretty much the same as the HttpPost function I showed in the last blog post.

We now have all the code we need to authenticate to Salesforce and read back a collection of Accounts. In the next post I will show how we display the Accounts.

3 comments:

Unknown said...

Excellent Article...

Unknown said...

Excellent Article...

Please remove the space between "=" symbol(back and forth)

redirect_uri=resttest:callback

TechTrendsIT said...

Excellent article..Well explained..Thanks for sharing..


TechTrendsIT