首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >无法在C#中反序列化嵌套JSON

无法在C#中反序列化嵌套JSON
EN

Stack Overflow用户
提问于 2022-02-15 22:52:28
回答 2查看 208关注 0票数 0

我对编程和C#很陌生。我正在使用(最新版本)编写我的应用程序。

这是一个控制台应用程序,它试图读取日志(文本)文件,其中每一行都是一个单独的JSON条目。

这就是一个JSON条目的样子:

代码语言:javascript
复制
{
    "timestamp": "2022-02-09T07:05:59Z",
    "event": "Color",
    "Hex": "#FFFF00",
    "Name": "Yellow"
}

我建立了文本文件的完整路径,并将其存储在字符串“fileFullPath”中,并且我正在“使用SystemT.ext.json”。

文本文件中的每个条目都有两个字段--“时间戳”和“事件”。我创建了一个名为“LogHeader”的基类:

代码语言:javascript
复制
namespace LogModels
{
    public class LogHeader
    {
        public string TimeStamp { get; set; }
        public string Event { get; set; }

    }
}

然后,我为每个事件创建了一个类,并继承自LogHeader:

代码语言:javascript
复制
public class Color : LogHeader
{
  public string Hex { get; set;}
  public string Name { get; set;}
}

接下来,我读取文件并开始遍历每一行并使用基于“event”字段的switch语句写入控制台:

代码语言:javascript
复制
foreach (string line in File.ReadAllLines(fileFullPath))
{
  var logHeader = JsonSerializer.Deserialize<LogHeader>(line,options);

  switch (logHeader.Event)
  {
     case "Color":
       var eventColor = JsonSerializer.Deserialize<LogModels.Event.Color>(line, options);
       Console.WriteLine($"The color is {eventColor.Name}.");
       Console.WriteLine($"The Hex value is {eventColor.Hex}.");
     break;
  }

控制台输出是:

颜色是黄色。

十六进制值为#FFFF00 00。

嵌套的JSON对象出现了问题,如下所示:

代码语言:javascript
复制
{
    "timestamp": "2022-02-09T07:07:52Z",
    "event": "Carpet",
    "Shag": [
        {
            "Color": "Green",
            "Count": 3
        },
        {
            "Color": "Black",
            "Count": 104
        }
    ],
    "Pile": [
        {
            "Color": "Blue",
            "Count": 5
        },
        {
            "Color": "Beige",
            "Count": 13
        }
    ],
    "Outdoor": [
        {
            "Color": "Pebble",
            "Count": 300
        },
        {
            "Color": "Astroturf",
            "Count": 12
        }
    ]
}

在这一点上,我迷路了。我尝试过创建一个名为“地毯”的类,它的子类名为"Shag“、”收尾“等等,我尝试为每个子类型创建单独的类。

所需的结果是将其显示在控制台上:

Shag地毯-

绿色:3

黑色: 104

绒毡-

蓝色:5

米色: 13

户外地毯-

鹅卵石: 300

草皮: 12

我无法想象这会像我想象的那样困难,但我似乎找不到任何例子来帮助我度过难关。

另外,我只在这个网站上贴了几次,我不确定回复建议的适当结构,等等。

谢谢你对我的帮助。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2022-02-15 23:20:28

由于您是编程新手和C#新手,我强烈建议您使用Newtonsoft.Json序列化程序。

你可以试试这段代码

代码语言:javascript
复制
Data data = JsonConvert.DeserializeObject<Data>(json);

代码语言:javascript
复制
public class Data
{
    [JsonProperty("timestamp")]
    public DateTime TimeStamp { get; set; }
    [JsonProperty("event")]
    public string Event { get; set; }
    public string Hex { get; set; }
    public string Name { get; set; }
    public List<ColourCount> Shag { get; set; }
    public List<ColourCount> Pile { get; set; }
    public List<ColourCount> Outdoor { get; set; }
}

public class ColourCount
{
    public string Color { get; set; }
    public int Count { get; set; }
}

可以使用反射进行测试。

代码语言:javascript
复制
    var props = data.GetType().GetProperties();

    foreach (var prop in props)
    {
        if (!prop.PropertyType.IsCollectible)
        {
            if(prop.GetValue(data)!=null)
            Console.WriteLine($" {prop.Name} : { prop.GetValue(data).ToString()} ");
        }
        else
        {
            Console.WriteLine($" { prop.Name} - ");

            var items = prop.GetValue(data) as IList<ColourCount>;

            foreach (var item in items)
            {
                Console.WriteLine($" {item.Color} : {item.Count}");
            }
        }
    }

结果

代码语言:javascript
复制
 TimeStamp : 2022-02-09 7:07:52 AM 
 Event : Carpet 
 Shag - 
 Green : 3
 Black : 104
 Pile - 
 Blue : 5
 Beige : 13
 Outdoor - 
 Pebble : 300
 Astroturf : 12

如果仍然希望使用Text.Json,请更改属性名称属性

代码语言:javascript
复制
Data data = System.Text.Json.JsonSerializer.Deserialize<Data>(json);

public class Data
{
    [JsonPropertyName("timestamp")]
    public DateTime TimeStamp { get; set; }
    [JsonPropertyName("event")]
    public string Event { get; set; }
    .....
}
票数 2
EN

Stack Overflow用户

发布于 2022-02-16 06:40:38

以下是我是如何做到的,感谢Serge的例子:

代码语言:javascript
复制
public class Carpet
{
    public List<ColourCount> Shag { get; set; }
    public List<ColourCount> Pile { get; set; }
    public List<ColourCount> Outdoor { get; set; }
}

public class ColourCount
{
    public string Color { get; set; }
    public int Count { get; set; }
}

在开关语句中:

代码语言:javascript
复制
  case "Carpet":
     var eventCarpet = JsonSerializer.Deserialize<LogModels.Event.Carpet>(line, options);

     foreach (var shag in eventMaterials.Shag)
     {
        Console.WriteLine($" {shag.Color}: {shag.Count}.");
     }

     foreach (var pile in eventMaterials.Pile)
     {
        Console.WriteLine($" {pile.Color}: {pile.Count}.");
     }

     foreach (var outdoor in eventMaterials.Outdoor)
     {
        Console.WriteLine($" {outdoor.Color}: {outdoor.Count}.");
     }

  break;

这使我获得了控制台所需的输出(减去“fluff”):

绿色:3

黑色: 104

蓝色:5

米色: 13

鹅卵石: 300

草皮: 12

我知道这可能是你所做的费希尔版本,但再次感谢你的帮助!

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/71134412

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档