Calling an asynchronous API in an ASP.Net application

I'm a bit new to ASP.Net and asynchronous coding, so bear with me. I wrote an asynchronous wrapper in C # for a web API that I would like to use in an ASP.Net application.

Here is one of the C # API wrapper functions:

public async Task<string> getProducts()
{
    Products products = new Products();
    products.data = new List<Item>();

    string URL = client.BaseAddress + "/catalog/products";
    string additionalQuery = "include=images";
    HttpResponseMessage response = await client.GetAsync(URL + "?" + additionalQuery);
    if (response.IsSuccessStatusCode)
    {
        Products p = await response.Content.ReadAsAsync<Products>();
        products.data.AddRange(p.data);

        while (response.IsSuccessStatusCode && p.meta.pagination.links.next != null)
        {
            response = await client.GetAsync(URL + p.meta.pagination.links.next + "&" + additionalQuery);
            if (response.IsSuccessStatusCode)
            {
                p = await response.Content.ReadAsAsync<Products>();
                products.data.AddRange(p.data);
            }
        }
    }
    return JsonConvert.SerializeObject(products, Formatting.Indented);
}

      

Then I have a WebMethod in my ASP.Net application (which will be called using Ajax from a Javascript file) that should call the getProducts () function.

[WebMethod]
public static string GetProducts()
{
    BigCommerceAPI api = getAPI();
    return await api.getProducts();
}

      

Now of course this won't work as WebMethod is not an asynchronous method. I tried changing it to an async method that looked like this:

[WebMethod]
public static async Task<string> GetProducts()
{
    BigCommerceAPI api = getAPI();
    return await api.getProducts();
}

      

This code runs, but as soon as it hits a string HttpResponseMessage response = await client.GetAsync(URL + "?" + additionalQuery);

in the getProducts () function, the debugger stops without any error or return.

What am I missing? How can I get this asynchronous API call from my ASP application?

0


source to share


3 answers


So, I actually solved a problem very similar to this last night. This is weird because the call worked in .net 4.5. But we moved on to 4.5.2 and the method started to stalled.

I found these enlightening articles ( here , here, and here ) on async and asp.net.

So, I changed the code to this

    public async Task<Member> GetMemberByOrganizationId(string organizationId)
    {
        var task =
            await
                // ReSharper disable once UseStringInterpolation
                _httpClient.GetAsync(string.Format("mdm/rest/api/members/member?accountId={0}", organizationId)).ConfigureAwait(false);

        task.EnsureSuccessStatusCode();

        var payload = task.Content.ReadAsStringAsync();

        return JsonConvert.DeserializeObject<Member>(await payload.ConfigureAwait(false),
            new JsonSerializerSettings { ContractResolver = new CamelCasePropertyNamesContractResolver() });
    }

      

which solved my deadlock problem.



So TL; DR: from Stephen Cleary's article

In the overview, I mentioned that when you expect an inline wait, the expected one will grab the current "context" and then apply that until the end of the async method. What exactly is this "Context"?

Simple answer:

If you are using the UI thread, then this is the UI context. If you answer to an ASP.NET request and then to an ASP.NET request context. Otherwise, it is usually a thread pool context. Complex answer:

If SynchronizationContext.Current is not null, then its current SynchronizationContext. (UI Request Contexts and ASP.NET Context Context Synchronization). Otherwise its current TaskScheduler (TaskScheduler.Default is the thread pool context).

and solution

In this case, you want awaiter not to capture the current context by calling ConfigureAwait and passing false

+1


source


I'm not sure what it is [WebMethod]

in ASP.NET. I remember it was SOAP web services, but no one is doing this as we have a web API with controllers where you can use async / await in action methods.

One way to test your code is to execute a synchronous asynchronous method using .Result

:

[WebMethod]
public static string GetProducts()
{
    BigCommerceAPI api = getAPI();
    return api.getProducts().Result;
}

      




As maccettura pointed out in a comment, this is a synchronous call and it blocks the thread. To make sure you don't have dead locks, follow Frans' advice and add .ConfigureAwait(false)

at the end of each asynchronous call in the method getProducts()

.

0


source


First, by convention GetProducts()

should be named GetProductsAsync()

.

Second, it async

does not magically allocate a new thread to call the method. async-await

is mainly about using naturally asynchronous APIs such as a network call to a database or a remote web service. When you use Task.Run

, you are explicitly using a thread-pooling thread to execute your delegate.

[WebMethod]
public static string GetProductsAsync()
{
    BigCommerceAPI api = getAPI();
    return Task.Run(() => api.getProductsAsync().Result);
}

      

Check this link This is a sample project on how to implement calling asynchronous web services in ASP.NET

0


source







All Articles