简体   繁体   中英

How to parse this 3rd party JSON service using .NET?

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, ie 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.

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"];

You are trying to deserialize into a model that doesn't match the response json at all! You have to create the model to match the response, for starters your model class should be named Request, and Data model should be a member of Request model and the type should be a List of List of the model type that you are trying now with.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM