C# 使用RestSharp反序列化具有未知键的字典
我目前得到一个JSON对象,其形状与以下类似:C# 使用RestSharp反序列化具有未知键的字典,c#,restsharp,json-deserialization,C#,Restsharp,Json Deserialization,我目前得到一个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": { "
{
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和rest填充到一个字典中,我目前有以下代码:
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; }
}
公共课程年
{
公共int值{get;set;}
公共字典数据{get;set;}
}
公共类数据
{
公共十进制总数{get;set;}
公共十进制低位{get;set;}
公共十进制中间值{get;set;}
公共十进制高位{get;set;}
公共十进制最小值{get;set;}
公共十进制最大值{get;set;}
}
我希望将Item1、Item2等作为字典的键,并将下面的值作为字典的值填充到数据类中。但它目前不起作用(我的结构的其余部分是,它只是最里面的部分)。我只是走错路了吗?我希望避免为Item1和Item2创建特定的类。步骤:
1。始终以逻辑方式塑造JSON对象
如果您以更合乎逻辑的方式重新构造json对象,这个问题将更容易处理。现在,与“值”处于同一级别的数据对象有n个,并且动态更改它们的属性名称
就我个人而言,我会将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; }
}
公共类基
{
[JsonProperty(“年”)]
公共列表年份{get;set;}
}
公课年
{
[JsonProperty(“价值”)]
公共int值{get;set;}
[JsonProperty(“数据”)]
公共列表数据{get;set;}
}
公共类数据
{
[JsonProperty(“名称”)]
公共字符串名称{get;set;}
[JsonProperty(“总计”)]
公共十进制总数{get;set;}
[JsonProperty(“低”)]
公共十进制低位{get;set;}
[JsonProperty(“Mid”)]
公共十进制中间值{get;set;}
[JsonProperty(“高”)]
公共十进制高位{get;set;}
[JsonProperty(“min”)]
公共十进制最小值{get;set;}
[JsonProperty(“max”)]
公共十进制最大值{get;set;}
}
步骤3:反序列化它
Base myYears = JsonConvert.DeserializeObject<Base>(myJsonString);
Base myYears=JsonConvert.DeserializeObject(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();
}
}
像这样使用它,例如:
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);
}
}
类程序
{
静态void Main(字符串[]参数)
{
字符串json=@”
{
“价值”:2013年,
“第1项”:{
“总计”:0.1044,
“低”:0.0143,
“中期”:0.1044,
“高”:0.3524,
“min”:0.0143,
“最大值”:0.3524,
},
“项目2”:{
“总计”:0.1702,
“低”:0.167,
“中期”:0.1702,
“高”:0.1737,
“min”:0.167,
“最大值”:0.1737,
}
}";
var years=JsonConvert.DeserializeObject(json);
}
}
感谢您的输入。我可能应该提到我对JSON格式没有控制权,我将在中编辑它。我试图避免引入另一个库,但我会记住JSON.Net。你可以将传入的JSON映射为你想要的样子,这样你就可以轻松地重新构造。我强调重新构造它,因为我认为模型实际上在逻辑上是不完整的。在“years”下面,有一堆属性、未知名称,其中一个是字符串,其余的是数据对象。我们不知道这些名称将是什么,因此我们甚至不知道将其绑定到什么C#变量名。另一种选择是使用这种方法:你可以编写自定义规则并覆盖赋值,使它看起来像你想要的那样,我想知道我如何在不反序列化的情况下重新映射JSON。您是否建议在使用之前操作JSON字符串以使其更易于解析?我发布的链接展示了如何为Json对象方法编写自定义规则,您可以覆盖常规的getter和setter,因此理论上,您应该能够将其与JsonProperty属性结合起来进行完全序列化。这是我希望您使用JavaScript而不是.NET的时候之一!
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);
}
}