Search code examples
dotnet-httpclientpostasync

HttpClient PostAsJsonAsync not working in Framework 4.6


I don't what it is, but the moment I run my project in debug mode and hits this line within PingServerAsync():

 var response = await httpClient.PostAsJsonAsync(url, payload);

it hangs for a sec, then just exists out with no response value. It's NOT hitting my Exception, nor is it logging the response.

public async Task CheckDicomServersAsync(string hostName)
    {
         ...
         var cstore = result.FirstOrDefault();
         MqttService.applog.Debug($"****** Gonna Dicom Echo this - {cstore.ClientAETitle} *******");
        string resp = await **PingDicomServerAsync**(cstore);
        Console.WriteLine($"Dicom Echo response: {resp}");
   }

private async Task<string> PingServerAsync(DICOMClient client)
    {

        EchoViewModelSettings payload = new EchoViewModelSettings();
        payload.ClientAE = client.ClientAETitle;
        // more props here..            
       
        using (httpClient)
        {
            httpClient.BaseAddress = new Uri(m_appConfig.DICOM_URL);
           
            var requestUri = handler + "/Echo?SessionID=" + System.Web.HttpUtility.UrlEncode(session.SessionID.ToString());

            try
            {
                MqttService.applog.Debug($"Make request: {requestUri}");

                var url = "http://localhost/MyDicomAPI/api/dicom/Echo?SessionID=my_session";

                // *** FIRE POST HERE ***
                var response = await httpClient.PostAsJsonAsync(url, payload);                    

                MqttService.applog.Debug($"The Response: {response.Content}");

                if (response.IsSuccessStatusCode)
                {
                    var echoResponse = await response.Content.ReadAsStringAsync();
                    MqttService.applog.Debug($"The Echo Response is: {echoResponse}");
                }                    
                if (response.StatusCode == System.Net.HttpStatusCode.OK)
                {
                    Console.WriteLine(response.StatusCode.ToString());
                    return response.StatusCode.ToString();
                }
                else
                {
                    return response.StatusCode.ToString();
                }
            }
            catch (Exception ex)
            {
                MqttService.applog.Error($"WTF is wrong now: {ex}");
                throw;
            }
            
            
        }
    }

Also checking this video tutorial as a reference - https://www.youtube.com/watch?v=VSAlIE2SFHw

Postman returns a response (value zero is success here) for the same URL and Json body:

enter image description here

*** UPDATE - Showing the calls from the beginning of Program.cs (i.e. temp bypass the Win Service) ***

 // **Program.cs**
 static void Main()
    {
        //ServiceBase[] ServicesToRun;
        //ServicesToRun = new ServiceBase[]
        //{
        //    new MqttService()
        //};
        //ServiceBase.Run(ServicesToRun);

        MqttService mqttSvc = new MqttService(); // debug version
        
        mqttSvc.**StartDebugMode**();
    }

    // **MqttService.cs**
    public void **StartDebugMode**()
    {
        Init();

        this.**CheckOtherServers**(hostName);

        //StartSubscriber();
        //StartPublisher();
        //PublishHeartBeat(null, null);            
    }

    private async void **CheckOtherServers**(string hostName)
    {
        if (this.pingDicom)
        {
            DicomStatus dicom = new DicomStatus();
            **await dicom.CheckDicomServersAsync(hostName);**
        }
    }

Solution

  • In general, you should avoid async void. One of the problems with async void is that the calling code doesn't know when the task completes. So your Main method just keeps on running until it reaches the end, at which point it exits Main, which exits your application.

    Use async Task instead of async void and await the task. On modern runtimes (i.e., .NET Core), you can have an async Task Main; on older platforms like the one you're targeting, you'll have to have Main block on the returned task instead of awaiting it. I.e., mqttSvc.StartDebugMode().GetAwaiter().GetResult().