Thursday, May 10, 2012

Windows Phone development: RestSharp and JSON response without a root object

Not everyone thinks alike, and not everyone builds the same.

RestSharp is, in lack of better words, freakin’ awesome. It rocks when it comes to Windows Phone web requests. There’s one little thing you should look out for though, and that’s the structure of the JSON response.

Basically, there’s two types: the root response type where the response has a root object that holds the response, and the rootless response type where the response lacks a root object and instead returns a collection of items at this point.

Parsing the first one is a piece of cake with RestSharp, all you have to do is something like

            RestSharp.IRestClient client = new RestSharp.RestClient("http://MyBaseUrlThatIsNotRealButOnlyAnExample.com");
            RestSharp.IRestRequest request = new RestSharp.RestRequest("MyResource/Example/IsAlso/NotReal");

            var asyncHandle = client.ExecuteAsync<MySampleObject>(request, response =>
            {
                // got the response..
            });

and you’re set. It automagically deserializes the json response to your model.

But.. (there’s always that “but”). If the object is rootless you might need to append a little extra at the beginning and end of the response prior to it being deserialized.

In this case all you have to do is make use of the OnBeforeDeserialization handler of the Request object.

            RestSharp.IRestClient client = new RestSharp.RestClient("http://MyBaseUrlThatIsNotRealButOnlyAnExample.com");
            RestSharp.IRestRequest request = new RestSharp.RestRequest("MyResource/Example/IsAlso/NotReal");
            request.OnBeforeDeserialization = response => {response.Content = string.Format("{0}{1}{2}", prefix, response.Content, suffix)};

            var asyncHandle = client.ExecuteAsync<MySampleObject>(request, response =>
            {
                // got the response..
            });

where “prefix” and “suffix” in the above code is the wrapper you need to make a root object surrounding the original response.

You can place it as a method instead if you want:

        private void AddPaddingToResponse(IRestResponse response)
        {
            response.Content = string.Format("{0}{1}{2}", "{\"features\":", response.Content, "}");

And use that for OnBeforeDeserialization (this is approach is more friendly for debugging purposes, the other is just a bit more cool and inline):

            RestSharp.IRestClient client = new RestSharp.RestClient("http://MyBaseUrlThatIsNotRealButOnlyAnExample.com");
            RestSharp.IRestRequest request = new RestSharp.RestRequest("MyResource/Example/IsAlso/NotReal");
            request.OnBeforeDeserialization = AddPaddingToResponse;

            var asyncHandle = client.ExecuteAsync<MySampleObject>(request, response =>
            {
                // got the response..
            });

And finally, a little sidenote: remember that you can Cancel the request if you want. Nice feature that helps with responsiveness of your app and is easily implemented by overriding the Back button event and simply calling:

            asyncHandle.Abort();

That’s it, and that’s that.

1 comment:

John S. said...

Can you post sample JSON for both scenarios? RestSharp supports 'rootless' data if it is an array returned. Just use Execute>() where T is a class that matches each of the items in the list.