Может ли кто-нибудь помочь мне в десериализации моих объектов JSON в C #?

1

Я пытаюсь преобразовать 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; }

}

Снимок экрана с моими нулевыми проблемами: http://i.imgur.com/XdYwlXo.gif

Теги:
deserialization
serialization
json.net

2 ответа

1
Лучший ответ

Поскольку у вашего JSON есть списки команд и игроков, смешанные с атрибутами игры (идентификатор даты и матча), вам нужно будет использовать пользовательский 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", отделяя дату и идентификатор соответствия от остальных элементов:

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);
  • 0
    Удивительно. Просто удивительно. Я чувствую, что был на правильном пути, но никогда не думал о классе Game <T> или об использовании собственного JsonConverter. Спасибо большое за вашу помощь.
  • 0
    Рад, что смог помочь.
0

У вас нет атрибута blueTeam или purpleTeam внутри вашего JSON.

Может быть, это должно выглядеть так:

    "teamStats": {
        "game2998": {
            "dateTime": "2014-05-23T19:00Z",
            "blueTeam": {
                "team304": {
                    "teamId": 304,
                    [...]
            }},
            "purpleTeam": {
                "team1": {
                    "teamId": 1,
                    [...]
            }},
            "matchId": "2515"
        }
  • 0
    Так что мои занятия не соответствуют Json, который я понимаю. Поэтому мне нужно избавиться от blueTeam и purpleTeam. Но вот мой следующий вопрос. В моих классах я должен объявить Словарь для КАЖДОЙ команды и КАЖДОГО игрока? общедоступный словарь <string, Team> team304 {get; set} открытый словарь <string, Team> team1 {get; установлен}. Это кажется невозможным, потому что в разных играх играют разные команды.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню