"The underlying connection was closed: An unexpected error occurred on a send."。邮递员也可以 headers

"The underlying connection was closed: An unexpected error occurred on a send.". Postman goes OK with same headers

场景

我正在尝试发出 WebRequest,但出现以下错误:

The underlying connection was closed: An unexpected error occurred on a send.

深​​入研究内部异常,我得到:

"Unable to read data from the transport connection: An existing connection was forcibly closed by the remote host."

执行请求的代码如下:

private static Hashtable exec (String method, String uri, Object data, String contentType) {
    Hashtable response;

    HttpWebRequest request = (HttpWebRequest)WebRequest.Create (API_BASE_URL + uri);

    request.UserAgent = "MercadoPago .NET SDK v"+MP.version; //version resolves to 0.3.4
    request.Accept = MIME_JSON; // application/json
    request.Method = method; //GET
    request.ContentType = contentType; //application/json
    setData (request, data, contentType); //setData in this case does nothing.

    String responseBody = null;
    try {
      HttpWebResponse apiResult = (HttpWebResponse)request.GetResponse (); //Error throws here
      responseBody = new StreamReader (apiResult.GetResponseStream ()).ReadToEnd ();

      response = new Hashtable();
      response["status"] = (int) apiResult.StatusCode;
      response["response"] = JSON.JsonDecode(responseBody);
    } catch (WebException e) {
      Console.WriteLine (e.Message);
    }
}

我已经做过的事情:

大约 4 天前,这些请求通过 c# 运行正常,但我突然开始遇到问题,但考虑到它对 Postman 的响应正常,我无法弄清楚问题出在哪里。

这是邮递员的回复

编辑: Fiddler 监听了两个请求。 Postman 的结果显示使用 HTTPS 对 API 的直接请求。当尝试使用我的 ConsoleApplication 时,它显示了一个 HTTP 请求,它建立了一个到 API 端点、端口 443 的隧道。

Fiddler 中用于隧道请求的 TextView 如下所示:

我注意到 "time" 字段指的是一个很旧的日期,但我不知道它是什么意思。

您可以试试下面的代码:

string url = ""; // url of the endpoint

WebClient client = new WebClient();
ServicePointManager.Expect100Continue = true;
ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3;
client.Encoding = Encoding.UTF8;
client.Headers.Add("content-type", "application/json"); // same as other parameters in the header

var data = client.DownloadString(url);

想通了。我需要包括使用 TLS1.2。

ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;

像这样启用 Tls12 是一种不好的做法-

ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;

将来,如果您需要使用更高版本的 TLS,则必须更新您的代码。

如果您使用的是旧版本的 .NET,只需将其切换到默认启用 Tls12 的更高版本即可。

例如,web.config 中的这个简单更改将自动启用 Tls12-

<httpRuntime targetFramework="4.6.1"/>

(作为有相同问题的其他人的参考)这也可能是 Double Hop 问题的结果,您应该将信用用户(在池中)传递给传递服务器或从一个环境到另一个环境,否则用户设置为 "ANONYMOUS/USER",您将得到一个 "An existing connection was forcibly closed by the remote host." 错误

我发现了同样的错误,只是提一下 request.UserAgent = "anything u want";