如何在 C# 中解析复杂的 JSON?最终我想在 DataGridView 中显示结果 [关闭]

Posted

技术标签:

【中文标题】如何在 C# 中解析复杂的 JSON?最终我想在 DataGridView 中显示结果 [关闭]【英文标题】:How to parse complex JSON in C#? Ultimately I want to display the result in DataGridView [closed] 【发布时间】:2021-06-25 11:38:54 【问题描述】:

这是我第一次在 C# 中解析复杂的 JSON,我对解析这样的 JSON 结构有点困惑。但是,我能够成功解析简单的 JSON。我在这里包括 JSON 和我遵循的方法:

[
    "L1": null,
    "L2": 
        "Name": "XXX",
        "contact": "xxxxx",
        "address": "XXXX"
    
,

    "L1": 
        "gender": "XXX",
        "contact": "xxxxx",
        "mail_address": "XXXX"
    ,
    "L2": null
]

我正在使用两个单独的类,如下所示:

public class L2

    public string Name get; set; 
    public string contact get; set; 
    public string address get; set; 


public class L1

    public string gender get; set; 
    public string contact get; set; 
    public string mail_address get; set; 


public class Root
     private L1 L1get;set;
     private L2 L2get;set;


我正在使用这些行来解析:

 string jsonText = File.ReadAllText("log_test.txt");
 List<Root> data = (List<Root>)JsonConvert.DeserializeObject<List<Root>>(jsonText);

当我运行它时,它运行时没有任何错误,但我的最终目标是在表格(或 DataGridView)中显示所有结果。如何访问每个属性?在第一个对象中,L1 没有任何字段,但在第二个对象中确实有字段。那么我该怎么做“L1.gender”?任何帮助表示赞赏。谢谢!!

【问题讨论】:

什么是parser?是一堂课吗?如果是这样,请edit你的问题包括它 感谢您的回复。是的,解析器是我的课。我只是稍微改变了我的问题和代码。你能看一下吗? 在根类中,L1 和 L2 是私有的,应该是公共的。 您可以使用null conditional operator 访问可能为空的成员的成员,例如root.L1?.gender。请参阅:How can I use the conditional null operator to check for null string?、Trying to understand ?. (null-conditional) operator in C# 或 Nullcheck multi level object。 事实上,这可能与那些重复,同意吗?如果没有,请edit您的问题以澄清您遇到的问题。也许您正在寻找类似Winforms DataGridView databind to complex type / nested property 或Is it possible to bind complex type properties to a datagrid? 的东西? 【参考方案1】:

您缺少 Json 的根类。 使用此站点https://json2csharp.com/ 创建所有类。 你会得到以下。 这将确保所有字段都已映射。

List<Root> myDeserializedClass = JsonConvert.DeserializeObject<List<Root>>myJsonResponse); 
public class L1

    public string gender  get; set; 
    public string contact  get; set; 
    public string mail_address  get; set; 


public class L2

    public string Name  get; set; 
    public string contact  get; set; 
    public string address  get; set; 


public class Root

    public L1 L1  get; set; 
    public L2 L2  get; set; 

【讨论】:

感谢您的回复。我很抱歉我错过了提到我已经包含了根类,它和你提到的一样。我仍然有问题。你给我的网站给了我根类型的 DeserialedClass,但你提到它是一个列表。它应该是一个列表,因为我有重复的数据? 是的,您的 json 是一个列表,所以我更改了网站上的代码以更好地匹配您的问题。 @PratikShrestha【参考方案2】:

Imo L1 和 L2 不是属性名称。并且有变量名。

我们可以定义一个 Contact 类:

public partial class Contact

    [JsonProperty("gender", NullValueHandling = NullValueHandling.Ignore)]
    public string Gender  get; set; 

    [JsonProperty("contact")]
    public string ContactContact  get; set; 

    [JsonProperty("mail_address", NullValueHandling = NullValueHandling.Ignore)]
    public string MailAddress  get; set; 

    [JsonProperty("Name", NullValueHandling = NullValueHandling.Ignore)]
    public string Name  get; set; 

    [JsonProperty("address", NullValueHandling = NullValueHandling.Ignore)]
    public string Address  get; set; 

然后反序列化 Like :

var result = JsonConvert.DeserializeObject<List<Dictionary<string, Contact>>>(input);
// result[0]["L2"] To access L2 values.

我们也可以将整个事情发送到List&lt;KeyPairValue..

var flatternResult = result.SelectMany(x=>x);
foreach (var contactInformation in flatternResult) 
    Console.Write($"\n\ncontactInformation.Key: is null? contactInformation.Value == null\n");
    Console.WriteLine(""
       +"\n Address         : "+ contactInformation.Value?.Address
       +"\n ContactContact  : "+ contactInformation.Value?.ContactContact
       +"\n Gender          : "+ contactInformation.Value?.Gender
       +"\n MailAddress     : "+ contactInformation.Value?.MailAddress
       +"\n Name            : "+ contactInformation.Value?.Name
    );


现场演示https://dotnetfiddle.net/9kGUj6

【讨论】:

你合并了两个单独的类吗? Dump 功能也对我不起作用。 转储功能是这个在线 Edi 特有的。它用于在屏幕上倾倒东西。我没有合并任何课程。我以为是一样的。两者在逻辑上没有区别。那些看起来像联系信息。我没有看到一个域,我会将性别与邮件配对,而不是与姓名或地址配对。序列化时可以忽略 Null 和空值。 为了显示名称例如你可以做contactInformation.Value.Name 对于 L1 L2 这件事很简单。你将如何处理 L3?你会重新编译所有代码来创建一个属性吗? @PratikShrestha - 我的主要目标是获取这些值并将其显示在 DataGridView 或 DataTable 上。你也可以帮我解决这个问题吗?另外,我将如何执行 LINQ 操作? - 堆栈溢出的规则是问one question per post,所以你应该问另一个问题。

以上是关于如何在 C# 中解析复杂的 JSON?最终我想在 DataGridView 中显示结果 [关闭]的主要内容,如果未能解决你的问题,请参考以下文章

在颤动中用数组解析复杂的JSON

在 C# 中解析嵌套的复杂 JSON 响应

使用 C# 解析复杂的 JSON

在 Pig 中解析复杂的 JSON 字符串

使用 C# 的复杂 JSON 对象序列化

如何出于 JSON 原因将元素附加到 C# 数组?