'How can I make sure that a webapi controller is getting the full data from an async method?

I have a webapi service and the controller of this service is calling a remote webapi to get data.

I have a sample controller which has the below test method :

    [HttpGet("activity")]
    public ActionResult<BoredAPIDM> GetActivity()
    {
        Processor pr = new Processor();
        object data = pr.GetActivity();
        Debug.WriteLine(data); // Breakpoint
        return Ok();
    }

and the Processor class has the below method :

    public async Task GetRemoteActivity()
    {
        string baseURL = $"https://www.boredapi.com/api/activity";

        using (var client = new HttpClient())
        {

            client.BaseAddress = new Uri(baseURL);
            client.DefaultRequestHeaders.Accept.Clear();
            client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

            HttpResponseMessage response = await client.GetAsync("activity");

            if (response.IsSuccessStatusCode)
            {
                string result = response.Content.ReadAsStringAsync().Result;
                DataTable dt = JsonConvert.DeserializeObject<DataTable>(result);
            }
            else
            {
                Debug.WriteLine($"Error calling the API from {baseURL}");
            }
        }
    }

As a result of this, what I am expecting is the data content which comes to the GetRemoteActivity() method but it does not come to GetActivity() method and the breakpoint on the debug line shows :

Id = 117, Status = WaitingForActivation, Method = "{null}", Result = "{Not yet computed}"

I feel like I am missing a whole point; what is it ?



Solution 1:[1]

There is a lot missing here so I’ll try to break it down for you:

  • object data = pr.GetActivity(); should this be calling GetRemoteActivity instead?
var data = await pr.GetRemoteActivity(); // prefix the current method with async
  • public async Task GetRemoteActivity() does not return a DataTable.
public async Task<DataTable> GetRemoteActivity()
  • using (var client = new HttpClient()) should be a singleton, never newed up per method call.

  • DataTable dt = JsonConvert.DeserializeObject<DataTable>(result); Are you sure this will bind to JSON correctly? I highly doubt it but inspect the API response. Likely this is going to need a separate DTO that matches the response.

  • The debugger returns Status = WaitingForActivation because you need to await the call. Awaitable calls lazy load and do not execute until you do a proper await.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 beautifulcoder