code first, ask questions later

Rest Web Services In Windows Phone 7

I’ve been messing around with some Window Phone 7 development lately and thought I would share how I have been calling web services with RestSharp (I’ve written a little about RestSharp previously using the google weather api).

var request = new RestRequest("accounts/ClientLogin", Method.POST); request.AddParameter("service", "reader", ParameterType.GetOrPost); request.AddParameter("accountType", "GOOGLE", ParameterType.GetOrPost); request.AddParameter("source", source, ParameterType.GetOrPost); request.AddParameter("Email",username, ParameterType.GetOrPost); request.AddParameter("Passwd", password, ParameterType.GetOrPost);

client.ExecuteAsync(request, (response) => { var auth = ParseAuthToken(response.Content); });</pre>

RestSharp will automatically build the request with the parameters it is given. These can be get/post, cookies or http headers. The ExecuteAsync method takes the request to make and an action to execute when finished.

I come from a web development background living the good life making synchronous requests. Developing in Silverlight requires a bit of an adjustment with a big focus on event driven asynchronous programming. The pattern I am using I’ve tried to avoid all the plumbing involved in hooking up and firing off event handlers. Here is the basic pattern I use for api calls, in this instance I am grabbing all the feed items for the given label:

public void GetLabelFeed(string label, Action<Model.Feed> success, Action<string> failure)
{
    string resource = "reader/api/0/stream/contents/user/-/label/" + label;

    var request = GetBaseRequest();
    request.Resource = resource;
    request.Method = Method.GET;
    request.AddParameter("n", 20); //number to return

    _client.ExecuteAsync<Model.Feed>(request, (response) =>
    {
        if (response.ResponseStatus == ResponseStatus.Error)
        {
            failure(response.ErrorMessage);
        }
        else
        {
            success(response.Data);
        }
    });
}

I pass two callbacks to the method, one for success and one for failure. In this example I am using RestSharp’s auto deserialzation into the class Model.Feed by calling ExecuteAsync<Model.Feed>(). Depending on the status of the request either failure or success action is called.

To use these methods in my wp7 application I use inline delegates to handle the events. One thing to be aware of is the code on these callbacks will run in the background thread and you wont see anything change on the UI. To fix this make sure the data binding code is executed in the UI thread using the dispatcher. I use a DispatcherHelper class borrowed from the MVVM Light Toolkit.

        
protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
{
	api.GetLabelFeed(
    	feedId,
    	(items) => DispatcherHelper.SafeDispatch(() =>
    	{
        	this.DataContext = items;
        	progressBar.Visibility = System.Windows.Visibility.Collapsed;
    	}),
    	(error) => DispatcherHelper.SafeDispatch(() =>
    	{
        	MessageBox.Show(error);
        	progressBar.Visibility = System.Windows.Visibility.Collapsed;
    	}));

    	base.OnNavigatedTo(e);
}

I found this structure has kept my code reasonable clean and has handled all cases in the simple web requests I have made but since I’m new to Silverlight I’m sure it could be better.

blog comments powered by Disqus