13

I realise there have been a number of similar posts to this but I haven't found a solution yet. Am trying to post some xml to an MPI gateway but keep getting the following error:

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

Below is the code I'm currently using but have tried just about every different approach I can think of and they all return the same error:

        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;

Am basically wandering if anyone can see anything that might be wrong with the code that could be causing this error or if it's most likely I problem on the their end? Have tried running on my localhost, our live server and my own private server (with a completely different IP) and still get same result.

Any ideas?

Wesley Bland
  • 8,816
  • 3
  • 44
  • 59
HuwD
  • 1,800
  • 4
  • 27
  • 58
  • Have you run the Service Trace Viewer Tool ? https://msdn.microsoft.com/en-us/library/ms732023.aspx ... also read http://stackoverflow.com/questions/7209823/an-existing-connection-was-forcibly-closed-by-the-remote-host-wcf – Paul Zahra Feb 11 '15 at 11:41
  • Have tried the Service Trace Viewer but hasn't revealed anything useful. Not showing any errors, – HuwD Feb 12 '15 at 09:15
  • Most likely your headers or your encoding is incorrect. Is there a website or other method that already does this and you are trying to emulate it? Or were you just provided instructions like 'just post the xml to this url and everything should work'? If there is an existing way to do this manually then I would recommend doing it the manual way but use a tool to view the headers being sent and then in your code you have to emulate the headers and formatting as best as possible. Posting data this way can be very tricky and it really helps to view the headers beforehand. – Joe Uhren Feb 18 '15 at 19:14
  • Thanks for help people, Turns out even though I'd ask the provider to verify the target url several times they'd given me the wrong url. I was not pleased. – HuwD Feb 20 '15 at 10:02

3 Answers3

33

I think its because you are connecting to "https" url. In this case you have to add following line to your code.

ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;

It will accept "ssl" protocol for your request. "ServicePointManager.ServerCertificateValidationCallback" handler just controls certificate validity.

Alisettar Huseynli
  • 944
  • 1
  • 11
  • 24
2

Slightly better perhaps:

System.Net.ServicePointManager.SecurityProtocol = System.Net.ServicePointManager.SecurityProtocol | System.Net.SecurityProtocolType.Tls12;
sapbucket
  • 6,795
  • 15
  • 57
  • 94
0

@AlisettarHuseynli is right, this sometimes has to do with https. Most likely occurs when the infrastructure gets updates which may mean TLS gets updated for example from TLS1.0 to TLS1.2 Usually happens with some APIs, etcetera.

If the service you are trying to access can be accessed over http, do that. Change the scheme from https to http. Worked in my case. Otherwise you'll have to add code to support higher versions of TLS. Popular software usually have an opt-in option to use TLS1.2 instead of the old TLS1.0.

Gilbert
  • 2,699
  • 28
  • 29