.Net 核心 Web API 调用其他外部 API

问题描述

我正在创建一个 .Net Core Web API,它将进一步调用外部 API。

场景:

在 .Net Core Web API 中,我想向 UiPath orchestrator API 发出 Post 请求以获取身份验证令牌。以下是我要提出的请求的链接 https://postman.uipath.rocks/#8f3b38d8-57dc-4d79-876d-0d2ff897f61a

[HttpPost]
public Task<IActionResult> GetAccesstoken()
{
  //Here I want to make a Post request to the API to Authenticate
}

这个响应(Auth token)将被发送到另一个post请求来启动一个进程 https://postman.uipath.rocks/#738c3beb-1c19-4257-8474-841a054c4220

[HttpPost]
 public Task<IActionResult> StartProcess(string token)
 {
   //Here I want to make a Post request to the other API in which token from the prevIoUs call will be 
    sent in header
 }

我必须在一两天内完成它,但我不知道如何才能做到这一点。

任何帮助将不胜感激。

解决方法

如果我正确理解您想要一个端点,它将向第三方 API 发出两个 POST 请求。第一个请求将检索授权令牌。第二个请求将使用其标头中的 Token 来传递授权。

要实现此行为,您的 API 中应该有一个端点,而不是两个端点(如上面的示例所示)。

另外,我建议您有一个单独的类,负责与您的第三方 API(使用 postman.uipath.rocks)进行通信。

因此,您调用第三方 API 的单个端点可能如下所示:

public class Controller
{
    // another Controller's code...
    private readonly IPostmanApi postmanApi;

    public Controller(IPostmanApi postmanApi)
    {
        this.postmanApi = postmanApi;
    }

    [HttpPost]
    public async Task<IActionResult> StartPostmanProcess()
    {
        string token = await postmanApi.GetToken();
        await postmanApi.StartProcess(token);

        return Accepted();
    }

    // another Controller's code...
}

您的 IPostmanApi.cs 文件可能如下所示:

public interface IPostmanApi
{
    ///<summary>
    /// A method to get Authorization Token from Postman
    ///</summary>
    Task<string> GetToken();

    ///<summary>
    /// A method to get start a process in Postman
    ///</summary>
    ///<param name="token">Postman's authorization token</param>
    Task StartProcess(string token);
}

您的 PostmanApi.cs 文件可能如下所示:

public class PostmanApi
{
    Task<string> GetToken()
    {
        using (HttpClient client = new HttpClient())
        {
            var response = await client.PostAsync("https://postman.uipath.rocks/#8f3b38d8-57dc-4d79-876d-0d2ff897f61a");

            // Note: this code assumes that the whole response body is a string Token.
            // If the `postman.uipath.rocks` returns an JSON object,which contains a
            // Token inside some field,you may use Newtonsoft.Json library to deserialize
            // it,and then retrieve your Token from corresponding field.
            // See example here: https://stackoverflow.com/questions/24131067/deserialize-json-to-array-or-list-with-httpclient-readasasync-using-net-4-0-ta
            return await response.Content.ReadAsStringAsync();
        }
    }

    Task StartProcess(string token)
    {
        using (HttpClient client = new HttpClient())
        {
            // Note: this code assumes that the `postman.uipath.rocks` receives
            // a **Bearer** token. If it receives another kind of authentication
            // scheme,you should use it instead of "Bearer".
            client.DefaultRequestHeaders.Authorization 
                         = new AuthenticationHeaderValue("Bearer",token);
            await client.PostAsync("https://postman.uipath.rocks/#738c3beb-1c19-4257-8474-841a054c4220");
    }
}

另外不要忘记在 IPostmanApi 内注册您的 Startup.cs 服务:

public void ConfigureServices(IServiceCollection services)
{
    // another code...

    services.AddScoped<IPostmanApi,PostmanApi>();
    // another code...
}

注意:

  1. 此代码不是线程安全的(因为 HttpClient 不是线程安全的)。如果您希望它是线程安全的,请考虑使用 IHttpClientFactory

有用的链接: