Search code examples
c#jquery.netdotnet-httpclienthttpresponsemessage

Calling HttpClient asynchronously to get the HttpResponseMessage via ajax


I am actually trying to fetch data through a URL using the HTTPClient class. I am calling via ajax call. However, when the response is fetched it gets back into running mode from debugging mode and nothing happens. No response is retrieved. Below is the code:

jQuery

$.ajax({
        type: "GET",
        contentType: "application/json; charset=utf-8",
        url: "../../Services/AService.asmx/GetCompanyInformation",
        data: { id: JSON.stringify(id) },
        contentType: "application/json; charset=utf-8",
        dataType: "json",
        async:true,
        success: function (res) {
            var options = JSON.parse(res.d);                   

        },
        error: function (errormsg) {
            $(".dropdown_SubDomainLoading").hide();
            toastr.options.timeOut = 7000;
            toastr.options.closeButton = true;
            toastr.error('Something Went Wrong');
        }
    });

WebMethod Call

public static string CompanyDetails;

    [WebMethod]
    [ScriptMethod(UseHttpGet = true)]
    public string GetCompanyInformation(string id)
    {
        string authorizationKey = "Bearer 5cae498ef11f128363c1fbb2761bbab40ac0e2e5";
        string url = string.Empty;
        url = GetCompanyDetailsForApps(id);
        RunAsync(url).Wait();
        return CompanyDetails;
    }

 static async Task RunAsync(string Url)
    {
        string authorizationKey = "Bearer 5cae498ef11f128363c1fbb2761bbab40ac0e2e5";
        try
        {
            using (var client = new HttpClient())
            {
                client.BaseAddress = new Uri(Url);
                client.DefaultRequestHeaders.Accept.Clear();
                client.DefaultRequestHeaders.Add("Authorization", authorizationKey);
                HttpResponseMessage response = await client.GetAsync(Url);

                if (response.IsSuccessStatusCode)
                {
                    string content = await response.Content.ReadAsStringAsync();
                    //UrlMetricsResponse mozResonse = JsonConvert.DeserializeObject<UrlMetricsResponse>(content);
                    dynamic dynObj = JsonConvert.DeserializeObject(content);
                    CompanyDetails = JsonConvert.SerializeObject(dynObj);
                }

            }
        }
        catch (Exception ex)
        {
            Console.WriteLine("ERROR :" + ex.Message);
        }

    }

As soon as the client.GetAsync() function is called, it comes back to run mode and nothing is fetched. Am I doing something wrong. How can i retrieve the response via the url?


Solution

  • Judging by [WebMethod], I'm guessing you are maintaining a very old ASP.NET application. The problem here is incompatible libraries. Old ASP.NET does not support async/await semantics, and HttpClient does not support synchronous HTTP operations.

    Your best option is to upgrade the application to something more modern that supports async controllers, such as ASP.NET Web API or ASP.NET Core. This way you won't have to block threads on HTTP calls. But if this is not an option, you need swap out HttpClient for a library that actually supports synchronous/blocking HTTP. Have a look at WebRequest or RestSharp. If you continue to use HttpClient and there are .Result or .Wait() calls anywhere on the call stack, you're not only blocking but you are inviting deadlocks.

    I can't stress this enough: HttpClient does not support synchronous HTTP, so if you can't switch to a more modern web framework, you must switch to an older HTTP library.