Question

I'm using HttpWebRequest and HttpWebResponse to get JSON from a WebAPI method. But I then need to serialize/deserialize/parse that data.

The native JavaScriptSerializer has been weighed and found wanting. I tried fastJSON, but it's documentation is woefully lacking; I rejected Simple.JSON because it is in Beta and I'm not sure it would support the Compact Framework for .NET 3.5. I finally turned to trusty old JSON.NET from Isaacsoft, but am stuck as to how to extract the pieces parts of the Json objects.

This is what I have so far:

const string uri = "http://localhost:48614/api/departments";
var webRequest = (HttpWebRequest)WebRequest.Create(uri);
var webResponse = (HttpWebResponse)webRequest.GetResponse();
if ((webResponse.StatusCode == HttpStatusCode.OK) && (webResponse.ContentLength > 0))
{
    var reader = new StreamReader(webResponse.GetResponseStream());
    string s = reader.ReadToEnd();
    MessageBox.Show(s);

    JsonArray depts = JsonConvert.DeserializeObject<JsonArray>(s);
    MessageBox.Show(string.Format("count is {0}", depts.Count)); // this is right; it shows 6
. . .

As shown in the last comment, the data I want is getting into depts, because the number it shows is correct - there are 6 JSON "records" (array members?) that display when "s" is messagebox.Shown().

But how to proceed from here? This commented out code will tell the sad tale of some of the directions into which I have flung my net, flailing about but so far failing:

//List<Department> ld = JsonConvert.SerializeObject(depts).to;
//foreach (JObject jso in depts)
//{
//    jso.Values()
//}
//object id, accountId, deptName;
//JToken id, accountId, deptName;
////foreach (JsonObject jso in depts)
////{
////    if (jso.TryGetValue("id", out id))
////    {
////        MessageBox.Show(id.ToString());
////    }
////}
//foreach (JObject jso in depts)
//{
//    if (jso.TryGetValue("id", id))
//    {
//        MessageBox.Show(id.ToString());
//    }
//}
//JsonObject dept = depts[0] as JsonObject;
//Department dept = depts[0] as Department;
//Department dept = depts[0].
//MessageBox.Show(string.Format("first record: id is {0}, accountId is {1}, deptName is {2}", dept.Id, dept.AccountId, dept.DeptName));
//int id = depts[0].
//string accountId = depts[0].AccountId;
//string deptName = depts[0].DeptName;

//MessageBox.Show(string.Format("accountId is {0}, deptName is {1}", accountId, deptName));

UPDATE

In response to Brian Rogers' request to see the json, this code:

var reader = new StreamReader(webResponse.GetResponseStream());
string s = reader.ReadToEnd();
MessageBox.Show(s);

...produces this:

enter image description here

UPDATE 2

Here is the test JSON:

[{"Id":0,"AccountId":"7.0","DeptName":"Dept7"},{"Id":1,"AccountId":"8.0","DeptName":"Dept8"},{"Id":2,"AccountId":"9.0","DeptName":"Dept9"},{"Id":3,"AccountId":"10.0","DeptName":"Dept7"},{"Id":4,"AccountId":"11.0","DeptName":"Dept7"},{"Id":5,"AccountId":"12.0","DeptName":"Dept8"}]

Was it helpful?

Solution

I'm not sure where you're getting the type JsonArray, but JSON.net uses JArray to represent a JSON array.

To access an item in the array, just use an indexer with the index of the item you want to get.

Then for each object, you can pretty much treat them as a dictionary and access members by name through the indexer.

Do note however that when you access anything through the indexer, you need to cast the value to the appropriate type. Accessing members will have the type JToken.

var json = @"[
    { ""Id"":0, ""AccountId"":""7.0"",  ""DeptName"":""Dept7"" },
    { ""Id"":1, ""AccountId"":""8.0"",  ""DeptName"":""Dept8"" },
    { ""Id"":2, ""AccountId"":""9.0"",  ""DeptName"":""Dept9"" },
    { ""Id"":3, ""AccountId"":""10.0"", ""DeptName"":""Dept7"" },
    { ""Id"":4, ""AccountId"":""11.0"", ""DeptName"":""Dept7"" },
    { ""Id"":5, ""AccountId"":""12.0"", ""DeptName"":""Dept8"" }
]";
var arr = JsonConvert.DeserializeObject<JArray>(json);
// iterate through all the objects
foreach (JObject obj in arr)
{
    var id = (string)obj["Id"];
    var accountId = (double)obj["AccountId"];
    var departmentName = (string)obj["DeptName"];
    // do stuff
}
var second = (JObject)arr[1]; // or directly access the second object

If you had targeted .NET 4, you could use dynamic to make things even easier.

dynamic arr = JsonConvert.DeserializeObject(json);
foreach (dynamic obj in arr)
{
    string id = obj.Id;
    double accountId = obj.AccountId;
    string departmentName = obj.DeptName;
    // do stuff
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top