【问题标题】:C# Flurl and HttpClient, no response from REST APIC# Flurl 和 HttpClient,没有来自 REST API 的响应
【发布时间】:2015-09-10 12:18:21
【问题描述】:

我在使用我的代码从 API 获取响应时遇到问题,请求没有超时,并且根本没有给我响应。我在自己的 API 中创建了一个 api 端点来返回 json 字符串,然后使用“Firefox Poster”手动发布 json 数据,它工作得很好。有了这个,我相信问题出在我的代码中。

我有一个 C# WebAPI,我正在开发它以与 Angular 前端一起使用(这可行,它只是为了历史记录)。调用我的 API 时,我创建了对象“EnrollmentRequestDto”

public class EnrollmentRequestDto
{
    /// <summary>
    /// Context Information for the request. Contains the Ship-To, language code and timezone.
    /// </summary>
    [JsonProperty("requestContext")]
    public RequestContextDto RequestContext { get; set; }
    /// <summary>
    /// Unique ID provided by DEP to reseller on provisioning DEP access. This would be the reseller's DEP ID if its posted by distributor OBO a reseller, and would be his own depResellerId if a reseller is posting for self.
    /// </summary>
    [JsonProperty("depResellerId")]
    public string DepResellerId { get; set; }
    /// <summary>
    /// Unique transaction ID provided by the reseller
    /// </summary>
    [JsonProperty("transactionId")]
    public string TransactionId { get; set; }
    /// <summary>
    /// List of orders in the transaction (limit 1000 per transaction)
    /// </summary>
    [JsonProperty("orders")]
    public List<OrderDto> Orders { get; set; }
}

创建此对象后,我将发送到我的类 RequestHandler 和 BulkEnrollRequest 方法,该方法使用 HttpClient 扩展 Flurl 编写,可在此处找到:github

public IResponse BulkEnrollRequest(EnrollmentRequestDto enrollmentRequest)
    {
        try
        {
            var result = _bulkEnrollUrl.PostJsonAsync(enrollmentRequest).ReceiveJson<SuccessResponse>();
            result.Wait();
            return result.Result;
        }
        catch (FlurlHttpTimeoutException)
        {
            throw new AppleTimeOutException();
        }
        catch (FlurlHttpException ex)
        {
            return _errorHandler.DeserializeFlurlException(ex);
        }
    }

我也试过这个以确保 Flurl 中没有任何事情发生(这只是为了调试到我想要得到响应的点):

public async Task<IResponse> BulkEnrollRequest(EnrollmentRequestDto enrollmentRequest)
    {
        var json = JsonConvert.SerializeObject(enrollmentRequest);

        var httpClient = new HttpClient();
        httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
        HttpResponseMessage response = await httpClient.PostAsync(_bulkEnrollUrl, new StringContent(json, Encoding.UTF8, "application/json"));

        return new SuccessResponse();
    }

代码在等待点冻结,什么也没有发生。我试图在 BulkEnrollRequest 之后放置一个断点,所以它永远不会离开这个方法。

现在是有趣的部分:它在我处理 ErrorHandler 时确实有效,并且在某些时候 API 停止响应。 Wireshark 显示正在发出请求……所以我卡住了。

感谢任何帮助。

编辑

现在可以了!我从 API Controller 一直到 RequestHandler 都实现了 async,然后等待每个调用。供参考:

public async Task<IResponse> BulkEnrollRequest(EnrollmentRequestDto enrollmentRequest)
    {
        try
        {
            var result = await _bulkEnrollUrl.PostJsonAsync(enrollmentRequest).ReceiveJson<SuccessResponse>();
            return result;
        }
        catch (FlurlHttpTimeoutException)
        {
            throw new AppleTimeOutException();
        }
        catch (FlurlHttpException ex)
        {
            return _errorHandler.DeserializeFlurlException(ex);
        }
    }

【问题讨论】:

  • 下载 fiddler 并将您的 http 请求与“Firefox Poster”发送的请求进行比较
  • 感谢您的评论,我就是这样做的,我找不到任何奇怪的请求。然而,我使用 Fiddler 发现我确实收到了来自 API 的响应,这正是我在代码中确定的“SuccessResponse”。我确实也进行了 Wireshark 跟踪,我认为流量看起来有点奇怪。没有明显的 RST 或 FIN ACK 告诉我交易已经结束...

标签: c# json flurl


【解决方案1】:

现在已修复。我认为 Wireshark 流量看起来如此奇怪的原因是代码中的死锁,而超时在我这边,这意味着我永远无法 FIN ACK 信息。为了解决这个问题,我在所有方法上实现了 async,从 Controller 到我的 RequestHandler 类。供参考:

public async Task<IResponse> BulkEnrollRequest(EnrollmentRequestDto enrollmentRequest)
    {
        try
        {
            var result = await _bulkEnrollUrl.PostJsonAsync(enrollmentRequest).ReceiveJson<SuccessResponse>();
            return result;
        }
        catch (FlurlHttpTimeoutException)
        {
            throw new AppleTimeOutException();
        }
        catch (FlurlHttpException ex)
        {
            return _errorHandler.DeserializeFlurlException(ex);
        }
    }

【讨论】:

  • 很高兴看到你没有放弃 Flurl ;)
  • 对我来说这里的关键是捕获 Flurl 特定的异常。直到其余代码完成后,它们才冒泡。捕获它们使我能够确定在执行其余代码后调试器中发生了什么。(逐步检查内部异常。)
【解决方案2】:

试试这个代码

安装包 Microsoft.AspNet.WebApi.Client

 using (var client = new HttpClient())
        {
            client.BaseAddress = new Uri("http://localhost:9000/");
            client.DefaultRequestHeaders.Accept.Clear();
            client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

            HttpResponseMessage response = await client.PostAsJsonAsync("api/products", enrollmentRequest);
            if (response.IsSuccessStatusCode)
            {
                var result = await response.Content.ReadAsAsync<T>();
            }
        }

【讨论】:

  • 它仍然在等待时冻结。就像我的代码无法以某种方式获取答案:)
猜你喜欢
  • 1970-01-01
  • 2017-08-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多