我正在尝试使用 Newtonsoft.Json 反序列化一些嵌套在 Json 响应中的对象。我想将以下 Jsons Term
对象反序列化到列表中。我在 Json 响应中有很多 Term
对象,因此性能和紧凑性对我来说很重要。我也只想定义 Term
类,因为我暂时不关心其他数据。
我有一个为 Term 定义的模型:
public class Term
{
public string Known { get; set; }
public string Word { get; set; }
}
我的 Json 看起来像这样:
{
"myName":"Chris",
"mySpecies":"Cat",
"myTerms":
[
{
"Term":
{
"Known":"true",
"Word":"Meow"
}
},
{
"Term":
{
"Known":"false",
"Word":"Bark"
}
}
]
}
我的 C# 反序列化代码:
var response = await httpClient.GetAsync(uri);
string responseString = response.Content.ReadAsStringAsync().GetResults();
var searchTermList = JsonConvert.DeserializeObject<List<Term>>(responseString);
我收到的问题/错误是,不确定如何从 json 响应中获取这些条款:
{Newtonsoft.Json.JsonSerializationException: Cannot deserialize the current
JSON object (e.g. {"name":"value"}) into type
'System.Collections.Generic.List`1[CoreProject.Models.Term]' because
the type requires a JSON array (e.g. [1,2,3]) to deserialize correctly.
To fix this error either change the JSON to a JSON array (e.g. [1,2,3]) or
change the deserialized type so that it is a normal .NET type (e.g. not a
primitive type like integer, not a collection type like an array or List<T>)
that can be deserialized from a JSON object. JsonObjectAttribute can also be
added to the type to force it to deserialize from a JSON object.
任何建议将不胜感激:)
最佳答案
您收到该错误是因为您试图将 JSON 反序列化为 List<T>
对于一些 T
(特别是 Term
),但根 JSON 容器不是一个数组,它是一个对象——一组无序的键/值对,被 {
包围和 }
-- 包含与您的 Term
相对应的相当深入嵌入的对象集合.
鉴于此,您可以使用 http://json2csharp.com/或 Paste JSON as Classes自动生成与您的 JSON 对应的完整数据模型,然后反序列化为该模型并选择出感兴趣的部分。
但是,如果您不想定义完整的数据模型,则可以通过将 JSON 加载到中间层中来选择性地反序列化相关部分 JToken
hierarchy然后使用
SelectTokens()
:
var root = JToken.Parse(responseString);
var searchTermList = root.SelectTokens("myTerms[*].Term")
.Select(t => t.ToObject<Term>())
.ToList();
注意事项:
查询字符串
"myTerms[*].Term"
包含 JSONPath通配符[*]
.该运算符匹配父元素"myTerms"
下的所有数组元素.Json.NET 支持 JSONPath 语法,如 Querying JSON with JSONPath 中所述.
如果 JSON 比您的问题中显示的更复杂,您可以使用 JSONPath 递归下降运算符
...
而不是找到Term
JSON 对象层次结构中任何级别的对象,例如:var searchTermList = root.SelectTokens("..Term") .Select(t => t.ToObject<Term>()) .ToList();
一旦选择了相关的 JSON 对象,您就可以使用
Jtoken.ToObject<Term>()
将每个反序列化为最终的 C# 模型。
样本 fiddle .
关于c# - 从嵌套在 Json 响应中的数组中反序列化对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46229165/