【问题标题】:Can't figure how to consume this API in C#不知道如何在 C# 中使用这个 API
【发布时间】:2019-06-03 02:21:09
【问题描述】:

请原谅我缺乏知识,我是一名数据库专家,虽然我不久前涉足了一点 C#。我想弄清楚如何让这个 API 运行。

我尝试使用的 API 来自 https://rapidapi.com/api-sports/api/api-nba/。几乎没有任何文档可以指导我。

这是我的代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using unirest_net.http;
using unirest_net;

namespace NBA_test
{
    class Program
    {
        public static void Main(string[] args)
        {
            Console.WriteLine("Start ...");

            Task<HttpResponse<MyClass.RootObject>> response = Unirest.get("https://api-nba-v1.p.rapidapi.com/gameDetails/5162")
            .header("X-RapidAPI-Host", "api-nba-v1.p.rapidapi.com")
            .header("X-RapidAPI-Key", "myKey")
            .asJsonAsync<MyClass.RootObject>();

            var status = response.Status;

            Console.WriteLine("End ....");
        }
    }

    public class MyClass
    {
        public class Result
        {
            public string seasonYear { get; set; }
            public int gameId { get; set; }
            public string arena { get; set; }
        }

        public class RootObject
        {
            public List<Result> results { get; set; }
        }
    }
}

var 状态从 Created 变为 Running,然后就是这样,程序关闭。没有错误消息,但我不知道如何从这个 API 中获取 JSON。我知道我错过了一些东西,但不知道是什么。

【问题讨论】:

  • 您的问题是如何使用异步/等待模式(Unirest.get 似乎是异步的,因为它返回Task)?如果是这样,this question 和 this question 可能会对您有所帮助。
  • 这太快了。只要给你的程序一个机会来提出这个请求。在 Main 方法的末尾添加 Console.ReadKey(); 行。
  • @cma-krv 你检查答案了吗?
  • @Ali Bahrami 是的,我做到了,他们都没有成功,所以我想弄清楚这一点。最近忙于家庭和工作,但很快就会回来。
  • 好的,所以我从异步调用切换到同步调用。我不断收到“System.InvalidCastException:'无法将'System.IO.MemoryStream'类型的对象转换为'RootObject'。'”错误消息。

标签: c# json unirest


【解决方案1】:

您在一个带有sync main 方法的控制台应用程序中。您不应该在 sync 方法中调用 async 方法。我已将您的 async 电话转为 sync 电话:

    public static void Main(string[] args)
    {
        Console.WriteLine("Start ...");

        var response = Unirest.get("https://api-nba-v1.p.rapidapi.com/gameDetails/5162")
        .header("X-RapidAPI-Host", "api-nba-v1.p.rapidapi.com")
        .header("X-RapidAPI-Key", "myKey")
        .asJson<RootObject>();

        var status = response.Status;

        Console.WriteLine("End ....");
    }

您仍然可能会问您的反序列化 JSON 在哪里?

根据Unirest docs:

回应 收到响应后,Unirest 在 对象的形式,该对象应始终具有相同的键 关于响应详细信息的每种语言。

.Code - HTTP 响应状态代码(示例 200) .Headers - HTTP 响应标头 .Body - 适用时解析的响应正文,用于 示例 JSON 响应被解析为对象/关联数组。 .Raw - 未解析的响应正文

基本上,您可以像这样访问您的结果:

if (response.Code == 200) // Success, OK in HTTP Codes
{
  response.Body; // which body has the type of MyClass.RootObject
}

完整的例子:

        public static void Main(string[] args)
        {
            Console.WriteLine("Start ...");

            var response = Unirest.get("https://api-nba-v1.p.rapidapi.com/gameDetails/5162")
            .header("X-RapidAPI-Host", "api-nba-v1.p.rapidapi.com")
            .header("X-RapidAPI-Key", "myKey")
            .asJson<RootObject>();

            if (response.Code == 200) // Success, OK in HTTP Codes
            {
              response.Body; // which body has the type of MyClass.RootObject
            }

            Console.WriteLine("End ....");

            Console.ReadLine(); // to force command line stay up for an input and not close applicaiton immediately aftter runing it.
        }

更新 1:

这是 Unirest 在 .NET Fiddle 上的生活和工作:

https://dotnetfiddle.net/EZDopa

【讨论】:

  • 我切换到同步调用,但我不断收到 "System.InvalidCastException: 'Unable to cast object of type 'System.IO.MemoryStream' to type 'RootObject' .'" 错误消息。
  • @CrnaKrv 我认为你是对的。我更新了代码并在 .NET Fiddle 上创建了一个活生生的例子,请看dotnetfiddle.net/EZDopa
  • 我做了更改,但仍然收到相同类型的消息:未处理的异常:System.InvalidCastException:无法将“System.IO.MemoryStream”类型的对象转换为“NBA_test”类型。根对象'。在 unirest_net.http.HttpResponse`1..ctor(HttpResponseMessage response) 在 unirest_net.http.HttpClientHelper.Request[T](HttpRequest request) 在 unirest_net.request.HttpRequest.asJson[T]()
【解决方案2】:

你可以使用httpClient

   using (var httpClient = new HttpClient())
        {
            httpClient.DefaultRequestHeaders.Add("User-Agent", "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36");
            var response = httpClient.GetStringAsync(new Uri(url)).Result;
            var releases = JArray.Parse(response);
        }

【讨论】:

    【解决方案3】:

    正如其他人指出的那样,您需要添加一些等待语句。我对 api 进行了多次调用,这些调用需要时间在我的一个应用程序中进行处理。根据我更新的其他 cmets,允许在您等待呼叫返回时执行逻辑。您的代码的编辑是:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using unirest_net.http;
    using unirest_net;
    
    namespace NBA_test
    {
    class Program
    {
        public static void Main(string[] args)
        {
            Console.WriteLine("Start ...");
            //the added Wait() causes the thread to hold until the task is finished.
            Task<HttpResponse<MyClass.RootObject>> response = Unirest.get("https://api-nba-v1.p.rapidapi.com/gameDetails/5162")
            .header("X-RapidAPI-Host", "api-nba-v1.p.rapidapi.com")
            .header("X-RapidAPI-Key", "myKey")
            .asJsonAsync<MyClass.RootObject>();
    
    
            //if need to perform other logic while you are waiting
            while(response.Status == TaskStatus.Running)
            {
             // perform other logic like gui here
            }
            var status = response.Status;
    
            Console.WriteLine("End ....");
        }
    }
    
    public class MyClass
    {
        public class Result
        {
            public string seasonYear { get; set; }
            public int gameId { get; set; }
            public string arena { get; set; }
        }
    
        public class RootObject
        {
            public List<Result> results { get; set; }
        }
    }
    

    }

    【讨论】:

    • 添加.Wait会导致应用死锁,不推荐。
    • @AliBahrami 是的,我同意等待会导致应用程序挂起,尽管我建议它的原因是在他的示例的上下文中,它会调用 .Wait() 或循环直到结果来自通话完成。
    • Unirest 已经有了sync 方法,所以不需要调用async 一个。
    【解决方案4】:

    原来 API 的文档有缺陷。我设法通过简单地使用字符串(和 Newtonsoft 的 Json.NET)使其工作。感谢@AliBahrami 的帮助。代码现在看起来像这样:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using unirest_net.http;
    using unirest_net;
    using Newtonsoft.Json.Linq;
    
    namespace NBA_test
    {
        public class Program
        {
    
            public static void Main(string[] args)
            {
    
                Console.WriteLine("Start of Program...");
    
                HttpResponse<string> response = Unirest.get("https://api-nba-v1.p.rapidapi.com/gameDetails/9999")
                .header("X-RapidAPI-Host", "api-nba-v1.p.rapidapi.com")
                .header("X-RapidAPI-Key", "myKey")
                .asJson<string>();
    
                var result = response.Body;
    
                JObject parsedString = JObject.Parse(result);
    
                RootObject myGame = parsedString.ToObject<RootObject>();
    
                // Get game id
                Console.WriteLine(myGame.results[0].gameId);
    
                Console.WriteLine("End of Program....");
            }
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2013-08-06
      • 1970-01-01
      • 1970-01-01
      • 2016-07-18
      • 2020-10-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多