【问题标题】:How to parse this 3rd party JSON service using .NET?如何使用 .NET 解析这个第 3 方 JSON 服务?
【发布时间】:2014-08-01 22:37:15
【问题描述】:

我正在尝试通过我的 .NET 桌面应用程序读取 Web 服务 api。我尝试了以下方法,但没有填充任何内容。通过 Fiddler,如果我单击 [Raw] 选项卡,响应如下所示:

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]]}]}

我想捕获数据点,即来自上述 JSON 段的“数据”。为此,我有一个简单的类如下:

public class DailySales
{
    public datetime Date { get; set; }
    public int UnitsSold { get; set; }
}

这是我的网络服务代码:

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  
}

任何关于我所缺少的提示将不胜感激。

【问题讨论】:

  • System.Net.Http 程序集中使用System.Net.Http.HttpClientWebClient 是旧的。
  • 您只想要data 积分?您正在尝试使用不匹配的类解析 json。

标签: c# .net json asp.net-web-api


【解决方案1】:

嗯,你的 json 没有反序列化,因为你的类模型根本不匹配。

首先,创建一个合适的模型(这是使用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; }
}

注意data 生成为List&lt;List&lt;object&gt;&gt;,因为它无法识别常见模式。您可以将其更改为包含 intDateTime 对象的类,但您必须手动将 JSON 中的 int 转换为 DateTime 对象。

在 webrequest 方面,您可以使用 HttpClient 以及 .NET 4.5 中的新 async-await 功能以及 Json.NET

public async Task RequestAndDeserializeJson()
{
    var httpClient = new HttpClient();
    var json = await httpClient.GetAsStringAsync("http://3rdPartySite.com");
    RootObject obj = JsonConvert.Deserialize<RootObject>(json);
}

如果只想提取data点,可以在Json.NET api中使用JObject.Parse

var jobject = JObject.Parse(json);

// Extract data points only
var dataPoints = jobject["project"]["data"];

【讨论】:

    【解决方案2】:

    您正在尝试反序列化为与响应 JSON 不匹配的模型。对于初学者,必须定义具有RequestList&lt;Project&gt; 成员的根模型类,并且data 字段应该是Request 类型为List&lt;List&lt;DailySales&gt;&gt; 的模型的成员。代码应如下所示:

    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; }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-12-29
      • 2016-05-22
      • 1970-01-01
      • 1970-01-01
      • 2019-05-12
      • 2020-08-11
      相关资源
      最近更新 更多