使用 System.Text.Json 反序列化奇形怪状的数据

Deserializing oddly shaped data using System.Text.Json

我正在从 Newtonsoft.Json 转换为 System.Text.Json,我遇到的数据如下所示:

    ...
    "people": {
      "ID001": {
        "id": "ID001",
        "surame": "Smith",
        "given": "Joe"
      },
      "ID002": {
        "id": "ID002",
        "surame": "Brown",
        "given": "George"
      }
    },
    ...

那里有一个额外的、不必要的关卡 "ID001"、"ID002" 等

因为它实际上是数据位于一个应该是标签的地方,所以我一直在弄清楚如何映射它,因为每条记录的 "label" 都不同。

(我还会注意到,我无法控制数据源;无法更改它)

使用 Newtonsoft,我会将整个 "People" 结构读入一个 Perople_Raw 对象,当使用动态解析时,我会序列化单个项目,剥离 "IDxxx" 值然后重新解析结果。

dynamic peopleArray = this.OverallDataObject.People_Raw
foreach (dynamic peopleItem in peopleArray) {
  string serialized = JsonConvert.SerializeObject(playerBio_raw);
  int posOpenBrace = serialized.IndexOf('{');
  Person person = JsonConvert.DeserializeObject<Person>(serialized.Substring(posOpenBrace));
  this.OverallDataObject.People.Add(person);
}

但是,

System.Text.Json 不支持这种愚蠢行为,那么如何指定映射以 Person 对象数组结束呢?通过一些包含外部 ID 和 Person 对象的中间对象?

System.Text.Json 支持反序列化为 Dictionary<string, TValue>,因此这将适用于您的数据:

public class Container
{
    public Dictionary<string, Person> People { get; set; }
}

public class Person
{
    public string Id { get; set; }

    public string Surame { get; set; }

    public string Given { get; set; }
}

来自 Newtonsoft.Json,同样重要的是要注意 System.Text.Json 根据 默认 区分大小写。确保设置 PropertyNameCaseInsensitive:

var options = new JsonSerializerOptions
{
    PropertyNameCaseInsensitive = true,
};
var deserialized = JsonSerializer.Deserialize<Container>(json, options);
Console.WriteLine(deserialized.People["ID001"].Given); // Joe

Fiddle 示例:https://dotnetfiddle.net/ipVpdu