0

我在使用 HttpClientFactory 时遇到了问题。我需要从一个第三方 Web api 调用两个 Web 方法。

  1. 获取订单号。
  2. 获取运输标签文件。

调用 #2 取决于 #1 的结果,因为它需要将 orderNumber 传递给它,例如:

await _client.getAsync("http://xxx/api/getLabel?orderNumber=[returnedOrderNumber]&fileType=1")

当我设置断点和调试时,它按预期工作。没有调试模式,#2 web 方法总是失败。我做过调查。如果我传递静态查询参数,例如:

http://xxx/api/getLabel?orderNumber=123&fileType=1

它工作正常。似乎 #2 在 orderNumber 给它之前评估查询字符串并执行 api 调用。非常令人沮丧,请您对这个问题有所了解吗?

在控制器上:

private readonly ISite1AuthHttpClient _site1HttpClient;

public OrderShippingOrdersController(site1AuthHttpClient)
{
    _site1HttpClient=site1AuthHttpClient
}

[HttpGet("{id}")]
public async Task<IActionResult> GetShippingLabel(int id)
{
    string token=await _site1HttpClient.GetToken(username.ToString(),password);
    string orderNumber=await _site1HttpClient.CreateOrder(Order,token);

    if (orderNumber!=null && orderNumber!="")
    {
        //this API call always failed during runtime. It works on debugging mode.
        var streamFile=(MemoryStream)(await _site1HttpClient.getShippingLabel(orderNumber,token));

    }
}

HttpClient 类型类:

public interface ISite1HttpClient
{
    Task<string> CreateOrder(AueCreateOrder order,string token);
    Task<Stream> GetShippingLabel(string orderNumber,string token);
}

public class Site1HttpClient:ISite1HttpClient
{
    private readonly HttpClient _client;

    public Site1HttpClient(HttpClient httpClient)
    {
        httpClient.BaseAddress = new Uri("http://abcapi.Site1.com/");
        httpClient.DefaultRequestHeaders.Accept.Clear();
        httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
        httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("text/plain"));

        _client = httpClient;
    }

    public async Task<string> CreateOrder(AbcCreateOrder order,string token)
    {
        var jsonInString=JsonConvert.SerializeObject(order);
        jsonInString="[ " + jsonInString + " ]";

        _client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer",token);
        HttpResponseMessage response = await _client.PostAsync(
            "api/AgentShipmentOrder/Create", new StringContent(jsonInString, Encoding.UTF8, "application/json"));

        if (response.IsSuccessStatusCode)
        {
            var contents = await response.Content.ReadAsStringAsync();
            AbcOrderCreateResponse abcRes = JsonConvert.DeserializeObject<AbcOrderCreateResponse>(contents);
            return abcRes.Message;
        }
        else
        {
            var errorResponse = await response.Content.ReadAsStringAsync();
            throw new Exception(errorResponse);
        }
    }

    public async Task<Stream> GetShippingLabel(string orderNumber,string token)
    {
        _client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer",token);
        HttpResponseMessage response = await _client.GetAsync("api/GetOrderLabel?orderId="+orderNumber+"&fileType=1");

        if (response.IsSuccessStatusCode)
        {
            Stream streamFile= await response.Content.ReadAsStreamAsync();
            return streamFile;
        }
        else
        {
            throw new Exception("failed to get label.");
        }
    }
}
4

1 回答 1

0
string token = _site1HttpClient.GetToken(username.ToString(),password);
string orderNumber = await _site1HttpClient.CreateOrder(Order,token);

我猜这个问题是因为第一个 await 关键字。当您对第一个函数调用(调用异步函数)使用 await 时,您声明您的程序不需要等待响应。因此,令牌变量在未设置时用于第二个函数。正如你在上面看到的,你应该很好地不用第一次等待 token 变量。

于 2018-12-16T20:25:26.050 回答