Load JSON data from web in Windows Phone

This post is about how to load JSON data from web server using HttpWebRequest in C# for Windows Phone application. Let’s say we have URL as follows:

http://api.domain.com/student?id=1

Which output JSON data with format:

Student
- id <int>
- name <string>
- cgpa <float>

First, declare the data contract, based on the JSON response format above.

using System.Runtime.Serialization
namespace MyApp
{
    [DataContract]
    public class Student
    {
        [DataMember]
        public int id { get; set; }

        [DataMember]
        public String name { get; set; }

        [DataMember]
        public float cgpa { get; set; }
    }
}

Then, create a http request using HttpWebRequest. It is discouraged to use WebClient because it is running synchronously, compared to HttpWebRequest, which is running asynchronously.

Using RequestState object is encouraged because during response callback, we are using this object to get the original http request, which can help prevent concurrency issues if this function is called simultaneously from different part of our program

In the http request asynchronous callback, we’ll parse the JSON string into C# objects, using DataContractJsonSerializer. 

using System.Net;
using System.Runtime.Serialization.Json;

// this is our request state class. should be declared within a namespace,
// but being simplified here for demo purposes
public class RequestState
{
    public HttpWebRequest Request { get; set; }
}

// method to request for data from web server. this should be within a class
public void GetData()
{
    String url = "http://api.domain.com/student?id=1";
    HttpWebRequest request = HttpWebRequest.CreateHttp(url);
    try
    {
        RequestState state = new RequestState()
        {
            Request = request
        };
        request.BeginGetResponse(request_BeginGetResponse, state);
    }
    catch (Exception e)
    {
        // error when sending http request
    }
}

// callback method that will be invoked asynchronously when
// http response finish being received
private void request_BeginGetResponse(IAsyncResult ar)
{
    try
    {
        RequestState state = (RequestState)ar.AsyncState;
        using (WebResponse response = state.Request.EndGetResponse(ar))
        {
            using (Stream stream = response.GetResponseStream())
            {
                DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(Student));
                Student student = (Student)serializer.ReadObject(stream);
                // handle received data here
            }
        }
    }
    catch
    {
        // exception when reading http response
    }
}