【问题标题】:C# Deserializing JSON with object inside list of objects - but cant acces itC# 使用对象列表中的对象反序列化 JSON - 但无法访问它
【发布时间】:2022-01-14 05:26:16
【问题描述】:

我有一个程序需要接收一个 JSON 对象,该对象包含一个带有对象列表的对象以及列表中每个对象内的一个对象。

访问“OuterGameResponse”中的对象没有问题,但用户名为空。我访问高分 lige 这个:

string json = @"{""Games"":[{""Highscore"":35,""Coinsgained"":35,""Starttime"":""2021-12-08T12:30:50.543766"",""User"":{""Username"":""Smorgaard""}},{""Highscore"":35,""Coinsgained"":0,""Starttime"":""2021-12-08T13:09:00.384853"",""User"":{""Username"":""Smorgaard""}},{""Highscore"":25,""Coinsgained"":25,""Starttime"":""2021-12-08T11:14:16.125606"",""User"":{""Username"":""Smorgaard""}},{""Highscore"":10,""Coinsgained"":10,""Starttime"":""2021-12-08T12:49:28.987071"",""User"":{""Username"":""Smorgaard""}},{""Highscore"":0,""Coinsgained"":0,""Starttime"":""2021-12-08T12:48:57.309838"",""User"":{""Username"":""Smorgaard""}}],""Message"":""OK"",""Code"":200}";

            GamesResponse _gr = JsonConvert.DeserializeObject<GamesResponse>(json);

            Console.WriteLine(_gr.Games[0].Highscore);

但不能这样做:

Console.WriteLine(_gr.Games[0].User.Username);

有没有办法做到这一点,而列表中的对象不为空?

下面是我想将 JSON 反序列化成的类。

[Serializable]
public class GamesResponse
{
    public List<OuterGamesResponse> Games;

    public string Message;
    public int Code;
}

[Serializable]
public class OuterGamesResponse
{
    public int Coinsgained;
    public int Highscore;
    public DateTime Starttime;
    public InnerGamesResponse User;
}

[Serializable]
public class InnerGamesResponse
{
    public string Username;
}

【问题讨论】:

  • 在 LINQPad 中测试,用户名属性已正确填充。问题中的代码是您的实际代码吗?
  • @LasseV.Karlsen 用户名字段.
  • 它仍然被正确填充。我复制并粘贴了问题中的代码,我得到了一个用该 console.writeline 语句编写的用户名,我可以看到所有字段都已填充。
  • 是的,但在讨论基于反射的 API 时,区别是相关的。

标签: c# json visual-studio json.net


【解决方案1】:

有什么办法吗

冒着您实际上并没有使用 Newtonsoft 的风险,并且为了我们的利益,您只是将前两行作为测试工具插入,而是使用例如System.Text.Json(可能通过一些 ReadAsJsonAsync Web 扩展调用隐式调用)及其默认设置,您应该注意,我们通常使用 properties 而不是字段来创建我们 de/ser 的类,例如:

public class GamesResponse
{
    public List<OuterGamesResponse> Games {get;set;}

    public string Message {get;set;}
    public int Code {get;set;}
}

{get;set;} 是将字段转换为属性所需的最少代码。

Newtonsoft 不那么挑剔,并且会 de/ser 属性或字段,但 System.Text.Json 不会 de/ser 字段,除非它是最新版本并且字段已标记为 [JsonInclude] 或您已指定它们应包含在序列化程序选项中

【讨论】:

    【解决方案2】:

    在实际代码中,我通过 Websocketshap 接收 JSON 数据,如下所示 - 问题是否会出现在这里?

    private GamesResponse _gr;
    
    public LeaderboardManager()
    {
        WebSocketClient.OnMessageEvent += this.OnMessage;
    }
    
    void OnMessage(object sender, MessageEventArgs e)
    {
        _dataRecieved = true;
    
        _gr = JsonConvert.DeserializeObject<GamesResponse>e.Data);
    }
    

    【讨论】:

    • 我个人不明白它是怎么做到的,但如果你仍然感到困惑,想将整个项目打包成一个 zip 文件并托管在某个地方(github 很常见,或者你甚至可以使用 this technique 将其放入 GIF 中,并将其作为图像添加到您的问题中,以便我们可以使用您的确切代码重现问题,然后我很乐意查看它
    • @CaiusJard 您的回复非常有帮助。我发现问题出现在服务器端,因为第一个种子用户名是 NULL,每次一开始都会使应用程序崩溃。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-02-10
    • 2014-08-04
    • 1970-01-01
    • 2016-12-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多