从Newtonsoft jObject提取属性

时间:2019-10-07 15:14:33

标签: c# rest api asp.net-core

我有一个.net核心控制台应用程序,我试图在其中获取返回的JSON对象内的两个属性的值。我已经突出显示了第43行的错误,请问有人可以告诉我我要去哪里错了!

错误:

  

System.ArgumentException:使用无效的键值“名称”访问的JArray值。预期为Int32数组索引。

     

在Newtonsoft.Json.Linq.JArray.get_Item(对象键)
  在PBXApp.Program.GetUser()中的C:\ Development \ PBXApp \ PBXApp \ Program.cs:line 43

返回的JSON:

{ 
   "results":[ 
      { 
         "name":"bulbasaur",
         "url":"https://pokeapi.co/api/v2/pokemon/1/"
      },
      { 
         "name":"ivysaur",
         "url":"https://pokeapi.co/api/v2/pokemon/2/"
      },
      { 
         "name":"venusaur",
         "url":"https://pokeapi.co/api/v2/pokemon/3/"
      }
   ]
}

Program.cs-

// retrieve asynchronous data from remote api
    public static async Task GetUser()
    {
        //baseUrl
        string baseUrl = "http://pokeapi.co/api/v2/pokemon/";
        try
        {
            // HttpClient implements a IDisposable interface
            using (HttpClient client = new HttpClient())
            {
                //initiate Get Request (await will execute the using statement in order)
                using (HttpResponseMessage res = await client.GetAsync(baseUrl))
                {
                    //get content from response, then convert it to a c# object
                    using (HttpContent content = res.Content)
                    {
                        //assign content to data variable by converting into a string using await
                        var data = await content.ReadAsStringAsync();
                        //convert data using newtonsoft JObject Parse class method
                        if (data != null)
                        {
                            //parse data into an object.
                            var dataObj = JObject.Parse(data)["results"];
enter code here
                            //ERROR ON THIS LINE
                            UserItem userItem = new UserItem(name: $"{dataObj["name"]}", url: $"{dataObj["url"]}");

                            //log userItem name and url to console
                            Console.WriteLine("Name:{0} Url:{1}", userItem.Name, userItem.Url);
                        }
                        else
                        {
                            Console.WriteLine("No returned data");
                        }
                    }
                }
            }
        }
        //exceptions
        catch (Exception exception)
        {
            Console.WriteLine(exception);
        }
    }

UserItem.cs-

public class UserItem
    {
        public UserItem(string name, string url)
        {
            Name = name;
            Url = url;
        }
        public string Name { get; set; }
        public string Url { get; set; }
    }

1 个答案:

答案 0 :(得分:0)

dataObj是一个JSON数组,但没有命名键。它只是一个常规数组。因此,您无法使用名为“ name”的键来访问它,因为该键不存在。

您可以使用数字索引,但是您事先(从JObject中)不知道数组有多长时间。因此最好将其解析为数组,然后遍历所有项目:

var dataObj = JArray.Parse(data)["results"];
foreach (var record in dataObj)
{
    var name = record["name"];
    // ...
}

但是,为什么要经历手动解析JSON的所有麻烦呢?只需创建类来保存结果,然后一次反序列化所有内容即可:

public class Pokémon
{
    public string name { get; set; }
    public string url { get; set; }
}

public class ListOfPokémon
{
    public List<Pokémon> results { get; set; }
}

var result = JsonConvert.DeserializeObject<ListOfPokémon>(jsonString);
foreach (var p in result.results)
{
    // ...
}