【问题标题】:Can anyone assist me in deserializing my JSON to C# Objects?谁能帮助我将我的 JSON 反序列化为 C# 对象?
【发布时间】:2014-05-28 09:46:52
【问题描述】:

我正在尝试将 JSON 转换为对象以轻松访问统计信息。我目前为我的字典和字典得到一个空值。如果有人可以提供帮助,将不胜感激。

这是我的 JSON 示例:

    {
"teamStats": {
    "game2998": {
        "dateTime": "2014-05-23T19:00Z",
        "team304": {
            "teamId": 304,
            "teamName": "Cloud9 ",
            "matchVictory": 1,
            "matchDefeat": 0,
            "baronsKilled": 2,
            "dragonsKilled": 4,
            "firstBlood": 0,
            "firstTower": 0,
            "firstInhibitor": 1,
            "towersKilled": 10
        },
        "team1": {
            "teamId": 1,
            "teamName": "Team SoloMid",
            "matchVictory": 0,
            "matchDefeat": 1,
            "baronsKilled": 0,
            "dragonsKilled": 1,
            "firstBlood": 1,
            "firstTower": 1,
            "firstInhibitor": 0,
            "towersKilled": 5
        },
        "matchId": "2515"
    }
},
"playerStats": {
    "game2998": {
        "dateTime": "2014-05-23T19:00Z",
        "matchId": "2515",
        "player328": {
            "playerId": 328,
            "kills": 1,
            "deaths": 1,
            "assists": 7,
            "minionKills": 254,
            "doubleKills": 0,
            "tripleKills": 0,
            "quadraKills": 0,
            "pentaKills": 0,
            "playerName": "Balls",
            "role": "Top Lane"
        },
        "player329": {
            "playerId": 329,
            "kills": 4,
            "deaths": 0,
            "assists": 7,
            "minionKills": 155,
            "doubleKills": 1,
            "tripleKills": 0,
            "quadraKills": 0,
            "pentaKills": 0,
            "playerName": "Meteos",
            "role": "Jungler"
        }
    }
}

}

这是我的课程示例:

 public class RootObject
{
    public Dictionary<string, GameT> teamStats { get; set; }
    public Dictionary<string, GameP> playerStats { get; set; }
}

public  class GameT
{
    public string dateTime { get; set; }
   public Dictionary<string, Team> blueTeam { get; set; }
   public Dictionary<string, Team> purpleTeam { get; set; }
    public string matchId { get; set; }
}

public class Team
{
    public int teamId { get; set; }
    public string teamName { get; set; }
    public int matchVictory { get; set; }
    public int matchDefeat { get; set; }
    public int baronsKilled { get; set; }
    public int dragonsKilled { get; set; }
    public int firstBlood { get; set; }
    public int firstTower { get; set; }
    public int firstInhibitor { get; set; }
    public int towersKilled { get; set; }
}
public class GameP
{
    public string dateTime { get; set; }
    public string matchId { get; set; }
    public Dictionary<string, Player> blueTop { get; set; }
    public Dictionary<string, Player> blueJungle { get; set; }




}
public class Player
{
    public int playerId { get; set; }
        public int kills { get; set; }
        public int deaths { get; set; }
        public int assists { get; set; }
        public int minionKills { get; set; }
        public int doubleKills { get; set; }
        public int tripleKills { get; set; }
        public int quadraKills { get; set; }
        public int pentaKills { get; set; }
        public string playerName { get; set; }
        public string role { get; set; }

}

我的 null 问题的屏幕截图: http://i.imgur.com/XdYwlXo.gif

【问题讨论】:

  • json 方案完全考虑到序列化/反序列化;没有办法让 json 更健全吗?
  • 你放在这里的json无效
  • 我正在从 API 中检索 Json,而 Json 本身就是一团糟。

标签: c# json serialization json.net deserialization


【解决方案1】:

由于您的 JSON 将球队和球员列表与游戏属性(日期和比赛 ID)混合在一起,因此您需要使用自定义 JsonConverter 以使其与您的类中的强类型字典一起使用。我将在下面解释如何做到这一点。

首先,像这样定义你的类:

public class RootObject
{
    public Dictionary<string, Game<Team>> teamStats { get; set; }
    public Dictionary<string, Game<Player>> playerStats { get; set; }
}

public class Game<T>
{
    public string dateTime { get; set; }
    public string matchId { get; set; }
    public Dictionary<string, T> items { get; set; }
}

public class Team
{
    public int teamId { get; set; }
    public string teamName { get; set; }
    public int matchVictory { get; set; }
    public int matchDefeat { get; set; }
    public int baronsKilled { get; set; }
    public int dragonsKilled { get; set; }
    public int firstBlood { get; set; }
    public int firstTower { get; set; }
    public int firstInhibitor { get; set; }
    public int towersKilled { get; set; }
}

public class Player
{
    public int playerId { get; set; }
    public int kills { get; set; }
    public int deaths { get; set; }
    public int assists { get; set; }
    public int minionKills { get; set; }
    public int doubleKills { get; set; }
    public int tripleKills { get; set; }
    public int quadraKills { get; set; }
    public int pentaKills { get; set; }
    public string playerName { get; set; }
    public string role { get; set; }
}

定义一个通用的 JsonConverter,它可以处理 JSON 的“游戏”部分,将日期和匹配 ID 与其余项目分开:

public class GameConverter<T> : JsonConverter
{
    public override bool CanConvert(Type objectType)
    {
        return (objectType == typeof(Game<T>));
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        JObject jo = JObject.Load(reader);
        Game<T> game = new Game<T>();
        game.dateTime = jo["dateTime"].ToString();
        game.matchId = jo["matchId"].ToString();
        game.items = new Dictionary<string, T>();
        foreach (JProperty prop in jo.Properties())
        {
            if (prop.Value.Type == JTokenType.Object)
            {
                game.items.Add(prop.Name, prop.Value.ToObject<T>());
            }
        }
        return game;
    }

    public override bool CanWrite
    {
        get { return false; }
    }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        throw new NotImplementedException();
    }
}

有了转换器,您可以按如下方式反序列化(注意我们需要两个转换器实例,一个用于处理球队列表,一个用于处理球员列表):

JsonSerializerSettings settings = new JsonSerializerSettings();
settings.Converters.Add(new GameConverter<Team>());
settings.Converters.Add(new GameConverter<Player>());

RootObject root = JsonConvert.DeserializeObject<RootObject>(json, settings);

【讨论】:

  • 太棒了。简直太神奇了。我觉得我走在正确的轨道上,但从未想过要使用 Game 类或使用自定义 JsonConverter。非常感谢您的帮助。
【解决方案2】:

您的 JSON 中没有名为 blueTeam 或 PurpleTeam 的属性。

也许应该是这样的:

    "teamStats": {
        "game2998": {
            "dateTime": "2014-05-23T19:00Z",
            "blueTeam": {
                "team304": {
                    "teamId": 304,
                    [...]
            }},
            "purpleTeam": {
                "team1": {
                    "teamId": 1,
                    [...]
            }},
            "matchId": "2515"
        }

【讨论】:

  • 所以我的课程与我理解的 Json 不匹配。所以我需要摆脱 blueTeam 和 PurpleTeam。但这是我的下一个问题。在我的课程中,我是否必须为每个团队和每个球员声明一个字典?公共字典 team304 {get;设置} 公共字典 team1 { 获取;放}。这似乎是不可能的,因为不同的球队在不同的比赛中比赛。
猜你喜欢
  • 2021-02-13
  • 1970-01-01
  • 2015-08-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-05-30
相关资源
最近更新 更多