使用asp.net核心API从外部API获取数据

Jef*_*ado 7 asp.net api asp.net-web-api

我正在学习使用ASP.NET核心创建API,为此我遇到了一个问题,我正在尝试使用我的API执行对外部API的请求,但是我不知道如何执行请求并返回请求的JSON,有帮助吗?

应用程序的流程如下所示:

SPA-> AspNet Core WEB API->外部API

到目前为止,我所做的是:

[Route("api/[Controller]")]
    public class RankingsController : Controller
    {
        private readonly IRankingRepository _rankingRepository;

        public RankingsController(IRankingRepository rankingRepo)
        {
            _rankingRepository = rankingRepo;
        }

        [HttpGet("{id}", Name = "GetRanking")]
        public IActionResult GetById(long id)
        //Here is where I want to make the requisition
        }

    }
Run Code Online (Sandbox Code Playgroud)

我需要为此API发出请求:

http://api.football-data.org/v1/competitions/ {id} / leagueTable

在ID位置,我需要传递一个参数,该参数来自API中的请求;

这个问题有帮助吗?

抱歉,您回答的不是这么复杂。

谢谢!!

Kar*_*ayo 7

您可以使用HttpClient实例来实现所需的功能。但是,我总是发现更容易使用RestSharp

当然,这将取决于您的约束,但是如果您在这种情况下没有约束,则可以使用RestSharp来调用外部API:

安装它:

Install-Package RestSharp

用法:

using RestSharp;

[HttpGet("{id}", Name = "GetRanking")]
public IActionResult GetById(long id)
{
    var client = new RestClient("http://api.football- 
    data.org/v1/competitions/445/leagueTable");
    var request = new RestRequest(Method.GET);
    IRestResponse response = client.Execute(request);

    //TODO: transform the response here to suit your needs

    return Ok(data);
}
Run Code Online (Sandbox Code Playgroud)

要使用RestSharp的其余响应,必须使用response.Content属性。

例如,您可以将其反序列化为Json,对其进行处理以满足您的需求,然后将所需的数据返回给您的API调用者。

例:

假设我想获得2017/18英超联赛的排名(Id = 445):

我将从传奇的Newtonsoft.Json包中获得很多帮助,并提供一些jpath语法,但是我假设您已经使用了这两种方法 :)

创建几个模型来保存要返回给API调用者的值:

public class LeagueTableModel
{
    public string LeagueCaption { get; set; }

    public IEnumerable<StandingModel> Standings { get; set; }
}
public class StandingModel
{
    public string TeamName { get; set; }

    public int Position { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

在服务类中实现以下方法,该方法通过DI / IoC注入到您的控制器中,以避免耦合并提高可测试性(众所周知,我们应该做对吗?)。我假设RankingRepository您的示例中包含此类:

public RankingRepository: IRankingRepository 
{
    public LeagueTableModel GetRankings(long id)
    {
        var client = new RestClient($"http://api.football-data.org/v1/competitions/{id}/leagueTable");
        var request = new RestRequest(Method.GET);
        IRestResponse response = client.Execute(request);
        if (response.IsSuccessful)
        {
            var content = JsonConvert.DeserializeObject<JToken>(response.Content);

            //Get the league caption
            var leagueCaption = content["leagueCaption"].Value<string>();

            //Get the standings for the league.
            var rankings = content.SelectTokens("standing[*]")
                .Select(team => new StandingModel
                {
                    TeamName = (string)team["teamName"],
                    Position = (int)team["position"]
                })
                .ToList();

            //return the model to my caller.
            return new LeagueTableModel
            {
                LeagueCaption = leagueCaption,
                Standings = rankings
            };
        }

        //TODO: log error, throw exception or do other stuffs for failed requests here.
        Console.WriteLine(response.Content);

        return null;
    }
}
Run Code Online (Sandbox Code Playgroud)

从控制器使用它:

[Route("api/[Controller]")]
public class RankingsController : Controller
{
    private readonly IRankingRepository _rankingRepository;

    public RankingsController(IRankingRepository rankingRepo)
    {
        _rankingRepository = rankingRepo;
    }

    [HttpGet("{id}", Name = "GetRanking")]
    public IActionResult GetById(long id)
        //Here is where I want to make the requisition
        var model = _rankingRepository.GetRankings(id);

        //Validate if null
        if (model == null)
            return NotFound(); //or any other error code accordingly. Bad request is a strong candidate also.

        return Ok(model);
    }
}
Run Code Online (Sandbox Code Playgroud)

希望这可以帮助!

  • 我建议使用基于异步和等待关键字的异步编程模型来提高响应速度。诸如此类:`public async Task &lt;IActionResult&gt; GetById(long id){IRestResponse response = await client.ExecuteAsync(request);` (2认同)