解析动态JSON

本文关键字:JSON 动态 | 更新日期: 2023-09-27 18:03:43

我正在使用c#和json.net 9.0.1

我有以下json
    {
        "lineups": [
          {
            "55": {
              "id": "55",
              "game_id": "1",
              "player_id": "55",
              "jersey_number": "78"
            },
            "56": {
              "id": "56",
              "game_id": "1",
              "player_id": "56",
              "jersey_number": "77"
            },
            "57": {
              "id": "57",
              "game_id": "1",
              "player_id": "57",
              "jersey_number": "76"
            }
        }
     ]
 }

所有数组项的类型都是Player。我如何解析json,使每个项目"55","56","57"存储在玩家列表,列表的列表?

源json不能被修改,因为它来自第三方。

修改json使其有效,

解析动态JSON

如果创建了这样两个类:

public class Lineup
{
    public List<Dictionary<string,Player>> lineups;
}
public class Player
{
    public string id {get; set; }
    public string game_id { get; set;}
    public string player_id {get;set;}
    public string jersey_number {get;set;}
}

那么你应该(在你修复了无效的JSON之后),能够像这样反序列化:

var l = Newtonsoft.Json.JsonConvert.DeserializeObject<Lineup>(source);

示例:https://dotnetfiddle.net/e7eUUZ

还可以使用JSON中的各种属性。Net自定义反序列化。例如,您可能希望使用JsonPropertyAttribute将JSON源中的名称映射到符合标准的c#属性名称。

给定这些类:

public class Lineup
{
    public List<Player> Players { get; set; }
}
public class Player
{
    public string id { get; set; }
    public string game_id { get; set; }
    public string player_id { get; set; }
    public string jersey_number { get; set; }
}
public class Result
{
    public List<Lineup> Lineups { get; set; }
}

你可以实现一个自定义的JsonConverter:

public class LineupConverter : JsonConverter
{
    public override bool CanConvert(Type objectType)
    {
        return objectType == typeof(Lineup);
    }
    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        if (reader.TokenType == JsonToken.Null)
            return null;
        if (reader.TokenType != JsonToken.StartObject)
            throw new Exception("Expected an object");
        var jObject = (JObject)JObject.ReadFrom(reader);
        // I suspect the property name are the same as the id property
        // of the contained objects. Discarding the information from serialization
        var players = jObject.Properties()
            .Select(p => p.Value.ToObject<Player>());
        return new Lineup
        {
            Players = players.ToList()
        };
    }
    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        throw new NotImplementedException();
    }
}

然后使用:

var lineups = JsonConvert.DeserializeObject<Result>(json, new LineupConverter());

您也可以用JsonProperty属性注释Player属性,使它们更像c#。