使用 RestSharp 反序列化具有未知键的字典

Deserialize Dictionary with unknown keys with RestSharp

我目前得到一个 JSON 对象,其形状类似于以下内容:

{
 more data here...
  "years": {
    "value": 2013,
    "item1": {
      "total": 0.1044,
      "Low": 0.0143,
      "Mid": 0.1044,
      "High": 0.3524,
      "min": 0.0143,
      "max": 0.3524,
    },
    "item2": {
      "total": 0.1702,
      "Low": 0.167,
      "Mid": 0.1702,
      "High": 0.1737,
      "min": 0.167,
      "max": 0.1737,
    },...
  }
}

不幸的是,我无法控制 JSON 的形状。

我正在尝试让 RestSharp 将其反序列化为一个对象,其中 Item1、Item2 和其余填充到字典中我目前有以下代码:

public class Year
{
    public int Value { get; set; }
    public Dictionary<string, Data> Data { get; set; }
}

public class Data
{
    public decimal Total { get; set; }
    public decimal Low { get; set; }
    public decimal Mid { get; set; }
    public decimal High { get; set; }
    public decimal Min { get; set; }
    public decimal Max { get; set; }
}

而我希望得到Item1、Item2等作为Dictionary的键和下面的值来填充Dataclass作为Dictionary的值。但它目前不起作用(我的结构的其余部分是,它只是最里面的部分)。我只是接近错误的结构吗?我想避免为 Item1 和 Item2 创建特定的 class。

步骤: 1。始终以合乎逻辑的方式塑造您的 JSON 对象

如果您以更合乎逻辑的方式重组 json 对象,这个问题会更容易处理。现在您有 n 个数据对象与 "value" 处于同一级别,并且您正在动态更改它们的 属性 名称。

就我个人而言,我会这样重塑 json:

{
   "years":[
      {
         "value":2013,
         "data":[
            {
               "name":"item1",
               "total":0.1044,
               "Low":0.0143,
               "Mid":0.1044,
               "High":0.3524,
               "min":0.0143,
               "max":0.3524
            },
            {
               "name":"item2",
               "total":0.1702,
               "Low":0.167,
               "Mid":0.1702,
               "High":0.1737,
               "min":0.167,
               "max":0.1737
            }
         ]
      }
   ]
}

第 2 步:将 Newtonsoft.Json 属性添加到您的 类

这样可以轻松反序列化

public class Base
{
    [JsonProperty("years")]
    public List<Year> years { get; set; }
}

    public class Year
    {
        [JsonProperty("value")]
        public int Value { get; set; }

        [JsonProperty("data")]
        public List<Data> data { get; set; }
    }

    public class Data
{
        [JsonProperty("name")]
    public string name { get; set; }
        [JsonProperty("total")]
        public decimal Total { get; set; }
        [JsonProperty("Low")]
        public decimal Low { get; set; }
        [JsonProperty("Mid")]
        public decimal Mid { get; set; }
        [JsonProperty("High")]
        public decimal High { get; set; }
        [JsonProperty("min")]
        public decimal Min { get; set; }
        [JsonProperty("max")]
        public decimal Max { get; set; }
    }

步骤 3:反序列化

Base myYears = JsonConvert.DeserializeObject<Base>(myJsonString);

您可以使用自定义 JsonConverter:

public class YearConverter : JsonConverter
{
    public override bool CanConvert(Type objectType)
    {
        return objectType == typeof(Year);
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        var obj = JObject.Load(reader);

        int year = (int)obj["value"];
        var data = new Dictionary<string, Data>();

        foreach (var dataItem in obj.Children()
            .OfType<JProperty>()
            .Where(p => p.Name.StartsWith("item")))
        {
            data.Add(dataItem.Name, dataItem.Value.ToObject<Data>());
        }

        return new Year
        {
            Value = year,
            Data = data
        };
    }

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

用转换器装饰你的 Year class:

[JsonConverter(typeof(YearConverter))]
public class Year
{
    public int Value { get; set; }
    public Dictionary<string, Data> Data { get; set; }
}

这样使用,例如:

class Program
{
    static void Main(string[] args)
    {
        string json = @"
{
  ""value"": 2013,
  ""item1"": {
    ""total"": 0.1044,
    ""Low"": 0.0143,
    ""Mid"": 0.1044,
    ""High"": 0.3524,
    ""min"": 0.0143,
    ""max"": 0.3524,
  },
  ""item2"": {
    ""total"": 0.1702,
    ""Low"": 0.167,
    ""Mid"": 0.1702,
    ""High"": 0.1737,
    ""min"": 0.167,
    ""max"": 0.1737,
  }
}";
        var years = JsonConvert.DeserializeObject<Year>(json);
    }
}