Http cannot send message to server

Viewed 150

I have a website solution written in .net framework 4.8 and I am trying to send JSON message over HTTP Post to a payment server and get a response, yet there is no error and no response message, it doesn't even time out. I tested the same code in another project, it is working fine but it is written in .net 5.0 (the latest and current).

I have no idea why the same code will yield such different results (although pointing to different versions of dll). Anyone can help me on this? Is there any documentation on this? I think that there is something can be done at the server side as well but I have no idea where to start. Basically I need my website to be able to "talk" to the payment server, but I'm stuck here.

Here's a snippet of my code

private static readonly HttpClient client = new HttpClient();

public static async Task<string> SubmitPaymentTransaction (string reqJsonstr)
    {
        try
        {
            HttpContent httpContent = new StringContent(reqJsonstr, Encoding.UTF8);
            httpContent.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/json");

            var message = new HttpRequestMessage();
            message.Content = httpContent;
            message.Method = HttpMethod.Post;
            message.RequestUri = new Uri($"https://payment.com/PayURL");

            HttpResponseMessage response = await client.SendAsync(message);
            response.EnsureSuccessStatusCode();
            string result = await response.Content.ReadAsStringAsync();

            return result;
        }
        catch(Exception error)
        {
            return error.ToString();
        }
        
    }

UPDATE:

I am able to capture the error message ... by removing the await: client.SendAsync(message)

InnerException = {"Authentication failed because the remote party has closed the transport stream."} 
Message = "The underlying connection was closed: An unexpected error occurred on a send." 
  at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) 
  at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
  at System.Runtime.CompilerServices.ConfiguredTaskAwaitable`1.ConfiguredTaskAwaiter.GetResult()
  at Mall.PayPlugin.Pay.PaymentCore.<SubmitPaymentTransaction>d__19.MoveNext()

I did a quick search on the error and it turns out the security protocol is the underlying issue. My web application is actually running on .net 4.5 so by default it is using TLS 1.0 which is unacceptable for the API server. Specifying the security protocol, I am able to get a response from the server, however, still at the expense of disabling the await.

1 Answers

Special thanks to @paulsm4 for helping, guiding and most importantly, inspiring me through solving this problem when I have almost given up.

The post and the comments should describe clearly the problem and my journey to the solution. I'm not going to repeat myself so I'm just going to share my code, which is working now for me.

private static readonly HttpClient client = new HttpClient();

private enum MySecurityProtocolType
{
    //
    // Summary:
    //     Specifies the Secure Socket Layer (SSL) 3.0 security protocol.
    Ssl3 = 48,
    //
    // Summary:
    //     Specifies the Transport Layer Security (TLS) 1.0 security protocol.
    Tls = 192,
    //
    // Summary:
    //     Specifies the Transport Layer Security (TLS) 1.1 security protocol.
    Tls11 = 768,
    //
    // Summary:
    //     Specifies the Transport Layer Security (TLS) 1.2 security protocol.
    Tls12 = 3072
}

public static async Task<string> SubmitPaymentTransaction (string reqJsonstr)
{
    try
    {
        HttpContent httpContent = new StringContent(reqJsonstr, Encoding.UTF8);
        httpContent.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/json");

        ServicePointManager.SecurityProtocol = (SecurityProtocolType)(MySecurityProtocolType.Tls12 | MySecurityProtocolType.Tls11 | 
                    MySecurityProtocolType.Tls | MySecurityProtocolType.Ssl3);

        var message = new HttpRequestMessage();
        message.Content = httpContent;
        message.Method = HttpMethod.Post;
        message.RequestUri = new Uri($"https://payment.com/PayURL");

        HttpResponseMessage response = await client.SendAsync(message).ConfigureAwait(false);
        response.EnsureSuccessStatusCode();
        string result = await response.Content.ReadAsStringAsync();

        return result;
    }
    catch(Exception error)
    {
        return error.ToString();
    }
    
}
Related