尝试从 C# 中的 API 调用反序列化 JSON 对象时出现错误。 (货币兑换)
Getting Errors when trying to Deserialize JSON object from API call in C#. (currency exchange)
我的目标是构建一个 API 可以将货币数据从 https://openexchangerates.org/ api 加载到我们的 SQLite 数据库中。我能够得到格式如下的 JSON 对象:
当我运行下面的代码时,它returns一个错误。我不确定如何解决这个问题。只需要将这个 JSON 转换成 C# class 没有错误。
这是要映射到 JSON 对象的自定义 C# 对象:
public class ExchangeRate
{
public string Disclaimer { get; set; }
public string License { get; set; }
public string Timestamp { get; set; }
public string Base { get; set; }
public string Rates { get; set; }
}
这是 api 返回错误的调用:
public static async Task GetLatest(string url)
{
var client = new HttpClient();
string results = await client.GetStringAsync(url);
List<ExchangeRate> ratesList = JsonConvert.DeserializeObject<List<ExchangeRate>>(results);
return ratesList;
}
示例JSON不是列表,它是单个对象,这在异常消息中指定
...because the type requires a JSON array
,否则它周围会有 [ ] 表示一个数组(可以反序列化为列表)。此外,您的模型存在缺陷,因为 Rates 不是一个字符串,而是一个对象,而 Timestamp 不是一个字符串,而是一个很长的日期时间作为刻度。像这样更改您的模型:
public class ExchangeRate
{
//decorate your properties since the json string uses lowercase
[JsonProperty("disclaimer")]
public string Disclaimer { get; set; }
[JsonProperty("license")]
public string License { get; set; }
[JsonProperty("timestamp")]
public long Timestamp { get; set; }
[JsonProperty("base")]
public string Base { get; set; }
[JsonProperty("rates")]
public Rates Rates { get; set; }
}
public class Rates
{
//create the properties for the Rates class
}
或将费率 属性 设置为 Dictionary<string, decimal>
,注意:如果任何密钥重复,这可能会失败。
public class ExchangeRate
{
//decorate your properties since the json string uses lowercase
[JsonProperty("disclaimer")]
public string Disclaimer { get; set; }
[JsonProperty("license")]
public string License { get; set; }
[JsonProperty("timestamp")]
public long Timestamp { get; set; }
[JsonProperty("base")]
public string Base { get; set; }
[JsonProperty("rates")]
public Dictionary<string, decimal> Rates { get; set; }
}
将您的代码更改为:
ExchangeRate rate = JsonConvert.DeserializeObject<ExchangeRate>(results);
您的 C# class 模型与传入的 JSON 数据结构不匹配。 Rates 是一个项目数组,但您将其视为 C# 模型中的字符串。时间戳是一个数字,但您将其视为 C# 模型中的字符串。
public class ExchangeRate
{
public string Disclaimer { get; set; }
public string License { get; set; }
public int Timestamp { get; set; }
public string Base { get; set; }
public Dictionary<string, double> Rates { get; set; }
}
我的目标是构建一个 API 可以将货币数据从 https://openexchangerates.org/ api 加载到我们的 SQLite 数据库中。我能够得到格式如下的 JSON 对象:
当我运行下面的代码时,它returns一个错误。我不确定如何解决这个问题。只需要将这个 JSON 转换成 C# class 没有错误。
这是要映射到 JSON 对象的自定义 C# 对象:
public class ExchangeRate
{
public string Disclaimer { get; set; }
public string License { get; set; }
public string Timestamp { get; set; }
public string Base { get; set; }
public string Rates { get; set; }
}
这是 api 返回错误的调用:
public static async Task GetLatest(string url)
{
var client = new HttpClient();
string results = await client.GetStringAsync(url);
List<ExchangeRate> ratesList = JsonConvert.DeserializeObject<List<ExchangeRate>>(results);
return ratesList;
}
示例JSON不是列表,它是单个对象,这在异常消息中指定
...because the type requires a JSON array
,否则它周围会有 [ ] 表示一个数组(可以反序列化为列表)。此外,您的模型存在缺陷,因为 Rates 不是一个字符串,而是一个对象,而 Timestamp 不是一个字符串,而是一个很长的日期时间作为刻度。像这样更改您的模型:
public class ExchangeRate
{
//decorate your properties since the json string uses lowercase
[JsonProperty("disclaimer")]
public string Disclaimer { get; set; }
[JsonProperty("license")]
public string License { get; set; }
[JsonProperty("timestamp")]
public long Timestamp { get; set; }
[JsonProperty("base")]
public string Base { get; set; }
[JsonProperty("rates")]
public Rates Rates { get; set; }
}
public class Rates
{
//create the properties for the Rates class
}
或将费率 属性 设置为 Dictionary<string, decimal>
,注意:如果任何密钥重复,这可能会失败。
public class ExchangeRate
{
//decorate your properties since the json string uses lowercase
[JsonProperty("disclaimer")]
public string Disclaimer { get; set; }
[JsonProperty("license")]
public string License { get; set; }
[JsonProperty("timestamp")]
public long Timestamp { get; set; }
[JsonProperty("base")]
public string Base { get; set; }
[JsonProperty("rates")]
public Dictionary<string, decimal> Rates { get; set; }
}
将您的代码更改为:
ExchangeRate rate = JsonConvert.DeserializeObject<ExchangeRate>(results);
您的 C# class 模型与传入的 JSON 数据结构不匹配。 Rates 是一个项目数组,但您将其视为 C# 模型中的字符串。时间戳是一个数字,但您将其视为 C# 模型中的字符串。
public class ExchangeRate
{
public string Disclaimer { get; set; }
public string License { get; set; }
public int Timestamp { get; set; }
public string Base { get; set; }
public Dictionary<string, double> Rates { get; set; }
}