7

I am having a problem with getting a response from an API with my code, the request does not time out and it does not give me a response at all. I have made an api endpoint in my own API to return the json string to then manually post the json data with "Firefox Poster" and it works just fine. With this I believe that the problem is somewhere in my code.

I got a C# WebAPI which I am developing to be used with an Angular frontend(This works, it's just for history). When calling my API I create the object "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; }
}

After this object is created I send to to my class RequestHandler and the method BulkEnrollRequest, which atm is written with HttpClient extension Flurl, which can be found here: 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);
        }
    }

I have also tried this to make sure that nothing happens in Flurl(This is just to debug to the point where I want to get the response):

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();
    }

And the code freezes at the await point and nothing is happening. I have tried to place a breakpoint after the BulkEnrollRequest so it never leaves this method.

Now here's for the funny part: It did work while I was working on the ErrorHandler and at some point the API just stopped responding. Wireshark shows that a request is being made... so I am stuck.

Any help is appreciated.

EDIT

This now works! I implemented async all the way from the API Controller down to RequestHandler, then awaited for every call. For reference:

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);
        }
    }
4

2 回答 2

5

现在已修复。我相信 Wireshark 流量看起来如此奇怪的原因是代码中的死锁,而超时在我这边,这意味着我永远无法 FIN ACK 信息。为了解决这个问题,我在所有方法上实现了异步,从 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);
        }
    }
于 2015-09-11T07:08:00.527 回答
0

试试这个代码

安装包 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>();
            }
        }
于 2015-09-10T12:30:46.747 回答