HTTP POST 错误:远程主机强制关闭了一个现有的连接

13

我知道已经有很多类似的帖子了,但我还没有找到解决方案。我试图将一些xml发布到MPI网关,但不断收到以下错误:

无法从传输连接中读取数据:远程主机强制关闭了一个现有的连接。

下面是我目前正在使用的代码,但我尝试了几乎所有我能想到的不同方法,它们都返回相同的错误:

        string result = "";

        string xml = "<TNSAuthRequest><CardNumber>0123456789</CardNumber><ExpiryDate>1801</ExpiryDate><PurchaseAmt>750</PurchaseAmt><CurrencyCode>826</CurrencyCode><CurrencyExponent>2</CurrencyExponent><CountryCode>826</CountryCode><MerchantName>Mayflower</MerchantName><MerchantId>0123456789</MerchantId><MerchantData>abcdefghijklmnopqrstuvwxyz0123456789</MerchantData><MerchantUrl>example.com</MerchantUrl><NotificationURL>example.com/basket</NotificationURL></TNSAuthRequest>";

        var url = "https://mpi.securecxl.com";
        byte[] bytes = System.Text.Encoding.ASCII.GetBytes("xmldata=" + xml.ToString());

        ServicePointManager.ServerCertificateValidationCallback += new System.Net.Security.RemoteCertificateValidationCallback(ValidateRemoteCertificate);

        var req = (HttpWebRequest)WebRequest.Create(url);
        req.AllowWriteStreamBuffering = true;
        req.ContentType = "text/xml";
        req.Method = "POST";
        //req.ContentLength = bytes.Length;
        req.KeepAlive = false;
        req.ProtocolVersion = HttpVersion.Version10;
        req.ServicePoint.ConnectionLimit = 1;
        //req.Timeout = -1;

        try
        {
            using (var writer = new StreamWriter(req.GetRequestStream(), Encoding.ASCII))
            {
                writer.WriteLine(bytes);
            }
            using (WebResponse resp = req.GetResponse())
            {
                using (StreamReader sr = new StreamReader(resp.GetResponseStream()))
                {
                    result = sr.ReadToEnd().Trim();
                }
            }
        }
        catch (Exception ex)
        {
            result = ex.Message + "<br />" + ex.InnerException.Message + "<br /><br />" + xml.Replace("<", "&lt;");
        }

        ViewBag.result = result;

我想知道是否有人能够看出代码中可能导致此错误的任何问题,或者这很可能是对方的问题? 我已经在我的本地主机、我们的实时服务器和我自己的私人服务器上尝试运行(具有完全不同的IP),但仍然得到相同的结果。

有任何想法吗?


你运行过服务跟踪查看器工具吗?https://msdn.microsoft.com/zh-cn/library/ms732023.aspx...还可以阅读https://dev59.com/8Ww05IYBdhLWcg3wfh2g - Paul Zahra
尝试过服务跟踪查看器,但没有显示任何有用的信息。没有显示任何错误。 - HuwD
很可能是您的标题或编码不正确。是否有一个网站或其他方法已经这样做,而您正在尝试模拟它?还是您只是提供了像“只需将xml发布到此url即可使一切正常”的指示?如果存在手动执行此操作的现有方法,则建议手动执行此操作,但使用工具查看发送的标头,然后在代码中尽可能模拟标头和格式。以这种方式发布数据可能非常棘手,事先查看标头确实有所帮助。 - Joe Uhren
感谢大家的帮助,结果尽管我多次要求提供商验证目标URL,他们仍然给了我错误的URL。我感到非常不满意。 - HuwD
3个回答

33

我认为原因在于您正在连接到“https” URL。在这种情况下,您需要将以下代码添加到您的代码中。

ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;

这将接受您的请求的“ssl”协议。“ServicePointManager.ServerCertificateValidationCallback”处理程序仅控制证书的有效性。


2
我已经成功访问了2年的Web服务突然在星期五停止工作。原来是这个问题。Web主机在星期五下午4点无预警地禁用了TLS 1.0。 - Matt Welch
我的代码在单元测试中可以运行,但一旦在IIS/IIS Express上托管就失败了。这个修复了它。 - denvercoder9
这真的非常有帮助。在我们公司,他们关闭了除TLS1.2之外的所有内容。 - Rufus Buschart
它也解决了我的问题 :) 我的主机API也突然停止工作了。看起来他也升级了TLS版本。 - vibs2006
1
2019年也是我的 :) - Suhas Dhongade
以下是不同.NET版本支持的TLS版本:stackoverflow.com/a/59687552/631277 - Matt Kemp

2
也许稍微好一点:
System.Net.ServicePointManager.SecurityProtocol = System.Net.ServicePointManager.SecurityProtocol | System.Net.SecurityProtocolType.Tls12;

0

@AlisettarHuseynli 是正确的,这有时与 https 有关。最可能发生的情况是当基础设施进行更新时,例如从 TLS1.0 升级到 TLS1.2,通常会发生在一些 API 等方面。

如果您要访问的服务可以通过 http 访问,请使用该协议。将方案从 https 更改为 http。在我的情况下起作用。否则,您将不得不添加代码以支持更高版本的 TLS。流行软件通常有一个选择性加入选项,以使用新的 TLS1.2 而不是旧的 TLS1.0


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接