使用 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);
}
}
我目前得到一个 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);
}
}