Reputation: 2179
I am trying to read a web service api via my .NET desktop application. I have tried the following, but nothing is being populated. Via Fiddler, if I click on the [Raw] tab, the response looks like:
HTTP/1.1 200 OK
Date: Fri, 01 Aug 2014 21:49:48 GMT
Server: Apache
X-Powered-By: PHP/5.3.3
Connection: close
Content-Length: 125478
Access-Control-Allow-Origin: *
Content-Type: application/json
Content-Language: en
{"request":{"command":"project","project_id":"XYZ123"},"project":[{"project_id":"XYZ123","name":"Project Financials","description":"Sales","state":"CA","dept":"Finance","modified":"2014-08-01","data":[["20140801", 112423],["20140731", 689944],["20140730", 9855], ["20140729", 13118], ["20140728", 9448],
... more data ...
["20140318", 1546], ["20140317", 5467], ["20140316", 19578], ["20140315", 90158]]}]}
I would like to capture the data points, i.e. the "data" from the above JSON segment. For this I have a simple class as follows:
public class DailySales
{
public datetime Date { get; set; }
public int UnitsSold { get; set; }
}
And here is my web service code:
private void GetSales()
{
var webClient = new WebClient();
webClient.OpenReadCompleted += webClient_OpenReadCompleted;
webClient.OpenReadAsync(new Uri("http://3rdPartySite.com"));
}
void webClient_OpenReadCompleted(object sender, OpenReadCompletedEventArgs e)
{
var json = new DataContractJsonSerializer(typeof(List<DailySales>));
var data = (List<DailySales>)json.ReadObject(e.Result); // returns null
}
Any tips on what I am missing would be appreciated.
Upvotes: 1
Views: 341
Reputation: 669
You are trying to deserialize the response into a class model that doesn't match the JSON. For starters your root model class has to be defined which would have the members request
of type Request
and project
of type List<Project>
.
Subsequently the data
field should be a member of Project
model with type List<List<DailySales>>
.
The class models would look like the following:
public class JsonRoot
{
public Request request { get; set; }
public List<Project> project { get; set; }
}
public class Request
{
public string command { get; set; }
public string project_id { get; set; }
}
public class Project
{
public string project_id { get; set; }
public string name { get; set; }
// Other Fields
public List<List<DailySales>> data { get; set; }
}
public class DailySales
{
public string Date { get; set; }
public int UnitsSold { get; set; }
}
Upvotes: 1
Reputation: 149538
Well, your json isn't deserializing because your class model doesn't match it at all.
First, create a proper model (this was generated using json2csharp):
public class Request
{
public string command { get; set; }
public string project_id { get; set; }
}
public class Project
{
public string project_id { get; set; }
public string name { get; set; }
public string description { get; set; }
public string state { get; set; }
public string dept { get; set; }
public string modified { get; set; }
public List<List<object>> data { get; set; }
}
public class RootObject
{
public Request request { get; set; }
public List<Project> project { get; set; }
}
Note data
is generated as a List<List<object>>
as it doesn't recognize a common pattern. You can change that to a class containing an int
and a DateTime
object, but you'll have to convert that int in your JSON to a DateTime
object manually.
On the webrequest side, you can use HttpClient
along with the new async-await
feature in .NET 4.5, along with Json.NET
:
public async Task RequestAndDeserializeJson()
{
var httpClient = new HttpClient();
var json = await httpClient.GetAsStringAsync("http://3rdPartySite.com");
RootObject obj = JsonConvert.Deserialize<RootObject>(json);
}
If you only want to extract the data
points, you can use JObject.Parse
in the Json.NET api:
var jobject = JObject.Parse(json);
// Extract data points only
var dataPoints = jobject["project"]["data"];
Upvotes: 3