C#HttpClient远程主机强制关闭现有连接

时间:2022-04-10 15:13:09

I'm working on an integration with Alternative Payments using their hosted page integration. Their C# SDK does not have this integration available at the moment, but as you can see it's pretty simple and I made a small class to send the post request and get the JSON response.

我正在使用托管页面集成与Alternative Payments进行集成。他们的C#SDK暂时没有这种集成,但正如你所看到的那样非常简单,我发了一个小类来发送post请求并获得JSON响应。

I tested the json object I'm sending on PostMan and cURL and both work, also the authentication header, so I think they are not the problem. Here is the constructor of my class:

我测试了我在PostMan和cURL上发送的json对象,两者都工作,也是认证头,所以我认为它们不是问题。这是我班级的构造函数:

public AlternativePaymentsCli(string apiSecretKey)
{
    this._apiSecretKey = apiSecretKey;

    _httpClient = new HttpClient();
    _httpClient.DefaultRequestHeaders.Accept
        .Add(new MediaTypeWithQualityHeaderValue("application/json"));

    var authInfo = _apiSecretKey;
    authInfo = Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(string.Format("{0}:", _apiSecretKey)));

    // The two line below because I saw in an answer on *.
    _httpClient.DefaultRequestHeaders.Add("Connection", "Keep-Alive"); 
    _httpClient.DefaultRequestHeaders.Add("Keep-Alive", "3600");

    _httpClient.DefaultRequestHeaders.UserAgent.ParseAdd("CSGOTroop.com custom client v1.0");
    _httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", authInfo);

}

And the method where I'm posting the data:

以及我发布数据的方法:

public string CreateHostedPageTransaction(HostedPageRequest req) 
{
    var settings = new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore };

    // I send this same json content on PostMan and it works. The json is not the problem
    var content = new StringContent(JsonConvert.SerializeObject(req, settings), Encoding.UTF8, "application/json");
    var response = _httpClient.PostAsync(this._baseUrl + "/transactions/hosted", content).Result;
    var responseText = response.Content.ReadAsStringAsync().GetAwaiter().GetResult();

    if (response.IsSuccessStatusCode)
        return responseText;

    return "";
}

Then I get this error: An existing connection was forcibly closed by the remote host, at the PostAsync line. This is the error details:

然后我收到此错误:远程主机在PostAsync行强行关闭现有连接。这是错误的详细信息:

[SocketException (0x2746): An existing connection was forcibly closed by the remote host]
   System.Net.Sockets.Socket.EndReceive(IAsyncResult asyncResult) +8192811
   System.Net.Sockets.NetworkStream.EndRead(IAsyncResult asyncResult) +47

[IOException: Unable to read data from the transport connection: An existing connection was forcibly closed by the remote host.]
   System.Net.TlsStream.EndWrite(IAsyncResult asyncResult) +294
   System.Net.ConnectStream.WriteHeadersCallback(IAsyncResult ar) +149

[WebException: The underlying connection was closed: An unexpected error occurred on a send.]
   System.Net.HttpWebRequest.EndGetRequestStream(IAsyncResult asyncResult, TransportContext& context) +324
   System.Net.Http.HttpClientHandler.GetRequestStreamCallback(IAsyncResult ar) +137

[HttpRequestException: An error occurred while sending the request.]

I'm using C# 4.5, Asp.Net MVC. I've been reading answers for the same error and none of them solved my issue so far. What am I missing in this code?

我正在使用C#4.5,Asp.Net MVC。我一直在阅读相同错误的答案,到目前为止,他们都没有解决我的问题。我在这段代码中缺少什么?

Thanks for any help

谢谢你的帮助

2 个解决方案

#1


18  

I don't see in your code sample where you are setting the value of _baseUrl, but I'm assuming that is being done somewhere. I'm also assuming that since this related to payments, the URL is HTTPS. If the remote host has disabled TLS 1.0 and your connection is coming in as TLS 1.0, it could cause that behavior. I know C# 4.6 has TLS 1.0/1.1/1.2 support enabled by default, but I think C# 4.6 still defaults to only SSL3/TLS 1.0 even though TLS 1.1 and 1.2 are supported. If this is the cause of the issue, you can manually add TLS 1.1 and 1.2 to the enabled values using the following code.

我没有在你的代码示例中看到你在哪里设置_baseUrl的值,但我假设这是在某个地方完成的。我还假设由于这与付款相关,因此URL是HTTPS。如果远程主机已禁用TLS 1.0并且您的连接以TLS 1.0的形式进入,则可能会导致该行为。我知道C#4.6默认启用了TLS 1.0 / 1.1 / 1.2支持,但我认为C#4.6仍然默认只支持SSL3 / TLS 1.0,即使支持TLS 1.1和1.2。如果这是问题的原因,您可以使用以下代码手动将TLS 1.1和1.2添加到启用的值。

System.Net.ServicePointManager.SecurityProtocol |= SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12;

#2


0  

If you are using .Net 4.0 then SecurityProtocolType.Tls11 and SecurityProtocolType.Tls2 are not defined so instead you can use the hard coded value below.

如果您使用.Net 4.0,则未定义SecurityProtocolType.Tls11和SecurityProtocolType.Tls2,因此您可以使用下面的硬编码值。

ServicePointManager.SecurityProtocol = (SecurityProtocolType)3072;

ServicePointManager.SecurityProtocol =(SecurityProtocolType)3072;

#1


18  

I don't see in your code sample where you are setting the value of _baseUrl, but I'm assuming that is being done somewhere. I'm also assuming that since this related to payments, the URL is HTTPS. If the remote host has disabled TLS 1.0 and your connection is coming in as TLS 1.0, it could cause that behavior. I know C# 4.6 has TLS 1.0/1.1/1.2 support enabled by default, but I think C# 4.6 still defaults to only SSL3/TLS 1.0 even though TLS 1.1 and 1.2 are supported. If this is the cause of the issue, you can manually add TLS 1.1 and 1.2 to the enabled values using the following code.

我没有在你的代码示例中看到你在哪里设置_baseUrl的值,但我假设这是在某个地方完成的。我还假设由于这与付款相关,因此URL是HTTPS。如果远程主机已禁用TLS 1.0并且您的连接以TLS 1.0的形式进入,则可能会导致该行为。我知道C#4.6默认启用了TLS 1.0 / 1.1 / 1.2支持,但我认为C#4.6仍然默认只支持SSL3 / TLS 1.0,即使支持TLS 1.1和1.2。如果这是问题的原因,您可以使用以下代码手动将TLS 1.1和1.2添加到启用的值。

System.Net.ServicePointManager.SecurityProtocol |= SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12;

#2


0  

If you are using .Net 4.0 then SecurityProtocolType.Tls11 and SecurityProtocolType.Tls2 are not defined so instead you can use the hard coded value below.

如果您使用.Net 4.0,则未定义SecurityProtocolType.Tls11和SecurityProtocolType.Tls2,因此您可以使用下面的硬编码值。

ServicePointManager.SecurityProtocol = (SecurityProtocolType)3072;

ServicePointManager.SecurityProtocol =(SecurityProtocolType)3072;