来自嵌套在JSON响应中的数组中的对象



我正在尝试使用newtonsoft.json嵌套在JSON响应中的某些对象。我想将以下JSONS Term对象列为列表。我在JSON响应中有许多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的JSON验证为某些T(特别是Term)的List<T>,但是root JSON容器不是数组,它是对象 - - 一组无序的密钥/值对,被{}包围 - 包含与您的Term相对应的对象的相当深的嵌入式集合。

考虑到,您可以使用http://json2csharp.com/或将json粘贴作为类,以自动化与您的JSON相对应的完整数据模型,然后对该模型进行应对化并选择有趣的部分。

但是,如果您不想定义完整的数据模型,则可以通过将JSON加载到中间JToken层次结构中,然后使用,然后使用 SelectTokens()

var root = JToken.Parse(responseString);
var searchTermList = root.SelectTokens("myTerms[*].Term")
    .Select(t => t.ToObject<Term>())
    .ToList();

注意:

  • 查询字符串"myTerms[*].Term"包含JSONPATH WIRDCARD操作员[*]。该操作员匹配父元素"myTerms"下的所有数组元素。

    JSON.NET支持JSONPATH语法,如JSONPATH查询JSON时所记录的。

  • 如果JSON比您的问题中显示的要复杂,则可以使用JSONPATH递归下降操作员...而不是在JSON对象层次结构中的任何级别找到Term对象,例如:

    var searchTermList = root.SelectTokens("..Term")
        .Select(t => t.ToObject<Term>())
        .ToList();
    
  • 选择了相关的JSON对象,您可以使用 Jtoken.ToObject<Term>()将每个对象都列为最终的C#模型。

样品小提琴。

尝试一下

public class Term
{
    public string Known { get; set; }
    public string Word { get; set; }
}
public class Response
{
    public List<TermWrapper> MyTerms { get; set; }
}
public class TermWrapper
{
    public Term Term { get; set; }
}
...
var response = await httpClient.GetAsync(uri);
string responseString = response.Content.ReadAsStringAsync().GetResults();
var searchTermList = JsonConvert
    .DeserializeObject<Response>(responseString)
    .MyTerms
    .Select(x => x.Term);

您必须考虑JSON的完整结构。您有一个具有3个属性的对象。您感兴趣的是一个对象数组,但是对象不是术语,它们是具有称为"术语"的属性的对象。该属性本身为Term类型。通过创建具有相似结构的类,您可以将所有必要的数据从结构中抽出。

相关内容

  • 没有找到相关文章

最新更新