我有以下从 API 返回的 JSON 字符串
{"success":true,"data":[
{"id":6,"order_nr":1,"name":"Capture Details","active_flag":true,"deal_probability":100,"pipeline_id":2,"rotten_flag":false,"rotten_days":null,"add_time":"2022-02-09 12:22:26","update_time":"2022-03-14 12:42:16","pipeline_name":"Stove Sales","pipeline_deal_probability":true},
{"id":19,"order_nr":2,"name":"Survey","active_flag":true,"deal_probability":100,"pipeline_id":2,"rotten_flag":false,"rotten_days":null,"add_time":"2022-02-15 13:45:03","update_time":"2022-03-14 12:42:16","pipeline_name":"Stove Sales","pipeline_deal_probability":true},
{"id":9,"order_nr":3,"name":"Quote","active_flag":true,"deal_probability":100,"pipeline_id":2,"rotten_flag":false,"rotten_days":null,"add_time":"2022-02-09 12:22:26","update_time":"2022-03-14 12:42:16","pipeline_name":"Stove Sales","pipeline_deal_probability":true},
{"id":10,"order_nr":4,"name":"Deposit Paid","active_flag":true,"deal_probability":100,"pipeline_id":2,"rotten_flag":false,"rotten_days":null,"add_time":"2022-02-09 12:22:26","update_time":"2022-03-14 12:42:16","pipeline_name":"Stove Sales","pipeline_deal_probability":true},
{"id":11,"order_nr":5,"name":"Order Stove","active_flag":true,"deal_probability":100,"pipeline_id":2,"rotten_flag":false,"rotten_days":null,"add_time":"2022-02-09 12:22:26","update_time":"2022-03-14 12:42:16","pipeline_name":"Stove Sales","pipeline_deal_probability":true},
{"id":12,"order_nr":6,"name":"Contract Agreed","active_flag":true,"deal_probability":100,"pipeline_id":2,"rotten_flag":false,"rotten_days":null,"add_time":"2022-02-09 12:22:26","update_time":"2022-03-14 12:42:16","pipeline_name":"Stove Sales","pipeline_deal_probability":true},
{"id":20,"order_nr":7,"name":"Send Full Ts&Cs for reply","active_flag":true,"deal_probability":100,"pipeline_id":2,"rotten_flag":false,"rotten_days":null,"add_time":"2022-03-14 12:42:16","update_time":"2022-03-14 12:42:16","pipeline_name":"Stove Sales","pipeline_deal_probability":true},
{"id":13,"order_nr":8,"name":"Install Stove","active_flag":true,"deal_probability":100,"pipeline_id":2,"rotten_flag":false,"rotten_days":null,"add_time":"2022-02-09 12:22:26","update_time":"2022-03-14 12:42:16","pipeline_name":"Stove Sales","pipeline_deal_probability":true},
{"id":14,"order_nr":9,"name":"Send Review","active_flag":true,"deal_probability":100,"pipeline_id":2,"rotten_flag":false,"rotten_days":null,"add_time":"2022-02-09 12:22:26","update_time":"2022-03-14 12:42:16","pipeline_name":"Stove Sales","pipeline_deal_probability":true},
{"id":15,"order_nr":1,"name":"Awaiting Sweep","active_flag":true,"deal_probability":100,"pipeline_id":3,"rotten_flag":false,"rotten_days":null,"add_time":"2022-02-12 17:57:35","update_time":"2022-02-12 17:57:35","pipeline_name":"Sweeps","pipeline_deal_probability":true},
{"id":16,"order_nr":2,"name":"Sweep Booked","active_flag":true,"deal_probability":100,"pipeline_id":3,"rotten_flag":false,"rotten_days":null,"add_time":"2022-02-12 17:57:35","update_time":"2022-02-12 17:57:35","pipeline_name":"Sweeps","pipeline_deal_probability":true},
{"id":17,"order_nr":3,"name":"Sweep","active_flag":true,"deal_probability":100,"pipeline_id":3,"rotten_flag":false,"rotten_days":null,"add_time":"2022-02-12 17:57:35","update_time":"2022-02-12 17:57:35","pipeline_name":"Sweeps","pipeline_deal_probability":true},
{"id":18,"order_nr":4,"name":"Send Review","active_flag":true,"deal_probability":100,"pipeline_id":3,"rotten_flag":false,"rotten_days":null,"add_time":"2022-02-12 17:57:35","update_time":"2022-02-12 17:57:35","pipeline_name":"Sweeps","pipeline_deal_probability":true}
]}
我在检查格式时添加的换行看起来没问题。我的 C# 数据类如下所示
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace PipedriveClient
{
internal class PipedriveStage
{
// Root myDeserializedClass = JsonConvert.DeserializeObject<Root>(myJsonResponse);
public class Datum
{
public int id { get; set; }
public int order_nr { get; set; }
public string name { get; set; }
public bool active_flag { get; set; }
public int deal_probability { get; set; }
public int pipeline_id { get; set; }
public bool rotten_flag { get; set; }
public object rotten_days { get; set; }
public string add_time { get; set; }
public string update_time { get; set; }
public string pipeline_name { get; set; }
public bool pipeline_deal_probability { get; set; }
}
public class Root
{
public bool success { get; set; }
public List<Datum> data { get; set; }
}
}
}
尝试解析它的代码看起来像
List<PipedriveStage.Root> stages;
using (var webClient = new WebClient())
{
var response = webClient.DownloadString(url);
JObject result = JObject.Parse(response);
var data = result.SelectToken("data");
stages = JsonConvert.DeserializeObject<List<PipedriveStage.Root>>(data.ToString());
}
检查响应的值,webClient 返回的响应字符串是相同的,所以我相信它应该可以解析。我的类(class)是通过使用 json2csharp.com 获得的,相同的基本代码对于同一 API 的其他返回工作正常。我一定只是遗漏了一些非常明显的东西,我希望你们中的一个人能跳出来!
最佳答案
您的 JSON 直接表示一个 PipedriveStage.Root
目的。由于某种原因,您正在解析为 JObject
, 选择 data
token(这是一个数组,但属于 Datum
),将其转换回字符串,然后将其作为 List<Root>
进行解析.
您可以将代码更改为:
var root = JsonConvert.DeserializeObject<PipedriveStage.Root>(response);
(您的 stages
变量在这里没有用 - 从逻辑上讲,您没有 多个要反序列化的根。)
我还建议:
- 使用
[JsonProperty]
将属性名称更改为惯用的 C#以指示它们在 JSON 中的表示方式。这将使您的 C# 代码看起来更“正常”。 (json2csharp.com 有“使用 Pascal 大小写”和“添加 JsonProperty 属性”的复选框,使这变得微不足道。) - 使用
HttpClient
而不是WebClient
- 避免嵌套类,除非你真的需要
关于c# - Json 解析失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71853967/