我正在尝试将json结果反序列化为想要的对象。我得到的结果是:
{
"base": "EUR",
"date": "2017-06-30",
"rates": {
"AUD": 1.4851,
"BGN": 1.9558,
"BRL": 3.76,
"CAD": 1.4785
}
}
我希望将此结果反序列化为我的对象:
public class ExchangeRates
{
public string Base { get; set; }
public DateTime Date { get; set; }
public IList<Rates> Rates { get; set; }
}
public class Rates
{
public string Name { get; set; }
public decimal Value { get; set; }
}
我的反序列化看起来像这样:
using (var httpClient = new HttpClient())
{
var response = httpClient.GetAsync("http://api.fixer.io/latest").Result;
var result = response.Content.ReadAsStringAsync().Result;
var values = JsonConvert.DeserializeObject<ExchangeRates>(result);
}
当我运行该程序时,我得到以下异常:
Newtonsoft.Json.JsonSerializationException:'无法将当前JSON对象(例如{“name”:“value”})反序列化为类型'System.Collections.Generic.List`1 [ConsoleApp4.Rates]',因为类型需要一个JSON数组(例如[1,2,3])正确反序列化。 要修复此错误,请将JSON更改为JSON数组(例如[1,2,3])或更改反序列化类型,使其成为普通的.NET类型(例如,不是像整数这样的基本类型,而不是类似的集合类型可以从JSON对象反序列化的数组或List。 JsonObjectAttribute也可以添加到类型中以强制它从JSON对象反序列化。 路径'rates.AUD',第1行,第49位。'
如何将JSON反序列化为我想要的对象?
更新1
或许我可以反序列化'费率'列表?
答案 0 :(得分:2)
看一下你的JSON,特别是rates
:
"rates": {
"AUD": 1.4851,
"BGN": 1.9558,
"BRL": 3.76,
"CAD": 1.4785
}
这显然是一个JSON对象,因为它具有键值对。但是,查看代码时,您已将相应的属性(Rates
)定义为IList
:
public IList<Rates> Rates { get; set; }
我理解你定义Rates
课程的原因。您认为通过定义该类,NewtonSoft将按您希望的方式反序列化rates
。但是,这是不可能的,因为rates
不是数组,因此将其反序列化为任何类型的IList
都是不可能的。
最简单,最明确的解决方案是使用字典:
public Dictionary<string, decimal> Rates { get; set; }
但是,如果您不想使用字典,则需要像这样修改您的JSON,并且您的解决方案将起作用:
"rates":[
{
"Name":"AUD",
"Value":1.4851
},
{
"Name":"BGN",
"Value":1.9558
},
{
"Name":"BRL",
"Value":3.76
},
{
"Name":"CAD",
"Value":1.4785
}
]
通过将rates
转换为数组,并使其内容对象而不是键值对,NewtonSoft可以将rates
反序列化为列表,并将其内容作为Rates
的实例进行反序列化类。
答案 1 :(得分:0)
我同意其他人的评论:你应该使用一个字典。要实现到最终对象结构的转换,您可以使用例如具有显式强制转换运算符的中间类。
using System;
using Newtonsoft.Json;
using System.Collections.Generic;
public class Program
{
public void Main()
{
var result = @"{
""base"": ""EUR"",
""date"": ""2017-06-30"",
""rates"": {
""AUD"": 1.4851,
""BGN"": 1.9558,
""BRL"": 3.76,
""CAD"": 1.4785
}}";
var values = (ExchangeRates) JsonConvert.DeserializeObject<TempExchangeRates>(result);
Console.WriteLine(values.Base);
Console.WriteLine(values.Date);
foreach(var rate in values.Rates)
Console.WriteLine(rate.Name + ": " + rate.
}
}
public class TempExchangeRates
{
public string Base { get; set; }
public DateTime Date { get; set; }
public Dictionary<string,decimal> Rates { get; set; }
public static explicit operator ExchangeRates(TempExchangeRates tmpRates)
{
var xRate = new ExchangeRates();
xRate.Base = tmpRates.Base;
xRate.Date = tmpRates.Date;
xRate.Rates = new List<Rates>();
foreach(var de in tmpRates.Rates)
xRate.Rates.Add(new Rates{Name = de.Key, Value = de.Value});
return xRate;
}
}
public class ExchangeRates
{
public string Base { get; set; }
public DateTime Date { get; set; }
public IList<Rates> Rates { get; set; }
}
public class Rates
{
public string Name { get; set; }
public decimal Value { get; set; }
}