All Blog Posts

WP7 Insights #1: Consuming REST APIs within a WP7 app

This article is the first in a series which discusses some of the things that I learned while developing my first Windows Phone 7 application. My first Windows Phone 7 application, Dwolla, was accepted into the marketplace about a month ago.  Our friends at Dwolla ( already had an app for the iPhone and Android platforms, but did not have any plans to pursue the WP7 platform in the near future.  I took this as an opportunity to learn about Windows Phone development and provide a tool for Dwolla consumers. Dwolla has REST APIs available for Developers.  After reviewing these APIs I had a couple of challenges in consuming these for Silverlight applications and WP7 apps.
  • Each API is a POST.  I had consumed APIs in Silverlight using GET, but not POST.
  • The results were returned in JSON format.  My background was consuming SOAP Web Services so JSON was a bit new to me.
Consuming the APIs in Silverlight After some research I came up with the following approach to consuming the Dwolla APIs.  Here is an example for the "account_information" method. I'll be working with parameters so I have the following. public string BuildParameters(Dictionary<string, string> parameters) { List<string> list = new List<string>(); foreach (string key in parameters.Keys) { list.Add(string.Format(""{0}" : "{1}"", key, parameters[key])); } return "{" + string.Join(",", list.ToArray()) + "}"; }   public class MyState { public HttpWebRequest Request { get; set; } public Dictionary<string, string> Parameters { get; set; } }   The following code sets up the API call.  A couple of things to note about this method.
  • Adding parameters was easy using the Dictionary and storing that in MyState class.
  • I had to set both the ContentType and Accept values for the HttpWebRequest object to "application/json" to get my method to work correctly.  I initially had ContentType but later found that I also needed Accept.
  private void GetAccountInformation(string email, string password) { try { DwollaLibrary dwollaLibrary = new DwollaLibrary();   string url = dwollaLibrary.GetDwollaJsonURL() + "/account_information";   Dictionary<string, string> parameters = new Dictionary<string, string>(); parameters.Add("APIUsername", dwollaLibrary.GetAPIKey()); parameters.Add("APIPassword", dwollaLibrary.GetAPICode()); parameters.Add("AccountIdentifier", email); parameters.Add("Password", password);   HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(url); request.Method = "POST"; request.ContentType = "application/json"; request.Accept = "application/json";   MyState state = new MyState(); state.Request = request; state.Parameters = parameters; request.BeginGetRequestStream(LoadRequestBegin, state); } catch (Exception) { myProgress.Visibility = Visibility.Collapsed; } }   Setup the parameters and call to get the response. private void LoadRequestBegin(IAsyncResult result) { try { var dwollaLibrary = new DwollaLibrary(); var state = (MyState)result.AsyncState; HttpWebRequest request = state.Request; using (Stream stream = request.EndGetRequestStream(result)) { using (StreamWriter writer = new StreamWriter(stream)) { string jsonParams = BuildParameters(state.Parameters); writer.Write(jsonParams); } } request.BeginGetResponse(LoadRequestComplete, request);   } catch (Exception) { myProgress.Visibility = Visibility.Collapsed; } }   Here is the method to handle the response.  Some notes:
  • I get the JSON results back in the response and get that string setup to load into my AccountInformation class.
  • I am using the DataContractJsonSerializer class to load the JSON string into my AccountInformation class.  Note the line where I declare "accountInformation".  The constructor of the AccountInformation class handles this.  This code is in the next section.
  private void LoadRequestComplete(IAsyncResult result) { try { string json = ""; this.Dispatcher.BeginInvoke(delegate() { try { HttpWebRequest request = (HttpWebRequest)result.AsyncState; WebResponse response = request.EndGetResponse(result); using (Stream stream = response.GetResponseStream()) { using (StreamReader reader = new StreamReader(stream)) { json = reader.ReadToEnd(); } }   string jsonResults = json.Replace("{"AccountInformationResult":", "").Replace("}}", "}"); var accountInformation = new AccountInformation(jsonResults); if (accountInformation.Id != "") { txtAccount.Text = accountInformation.Id; txtBalance.Text = string.Format("{0:C}", accountInformation.Balance); } myProgress.Visibility = Visibility.Collapsed; } catch (Exception) { myProgress.Visibility = Visibility.Collapsed; } }); } catch (Exception ex) { myProgress.Visibility = Visibility.Collapsed; } }   Parsing out the data.  I found that the DataContractJsonSerializer class is pretty cool - parses the JSON string into my class automagically.  The following code snippets accomplishes this.   using System.Runtime.Serialization.Json; using System.IO; using System.Text;   namespace DwollaApp.Components { public static class Extensions { public static T FromJSON<T>(this T obj, string json) where T : class { using (MemoryStream stream = new MemoryStream(Encoding.Unicode.GetBytes(json))) { DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(T)); return serializer.ReadObject(stream) as T; } } }   public class AccountInformation { public AccountInformation() { }   public AccountInformation(string json) { AccountInformation accountInfo = this.FromJSON(json);   _id = accountInfo.Id; _name = accountInfo.Name; } ... } } Once I had this framework in place I was able to use this approach for all of my API calls.  If you have a WP7 phone you can download the Dwolla app and give it a try.  You will need to setup a free account at to establish your account. Happy coding!