Wow, it’s been a while…
I’ve been testing the REST API for Salesforce’s Radian6. It’s very straightforward, but I spent HOURS trying to get it to work in .NET (C#). I thought that it made sense to further document it here, and hopefully up the Google hit count.
Making a REST call in .NET is a no-brainer. Simple code like the following should do the trick:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
protected string Call_Rest() { //REST call: using (WebClient client = new WebClient()) { //add HTTP headers (for auth) client.Headers.Add("auth_appkey", auth_appkey); if (auth_token == null || auth_token.Trim() == "") { client.Headers.Add("auth_user", auth_user); client.Headers.Add("auth_pass", auth_pass); } else { client.Headers.Add("auth_token", auth_token); } //send web request; get web response as XML try { responseXml = client.DownloadString(url); } catch (Exception exc) { responseXml = "ERROR: " + exc.Message; } } return responseXml; } |
The problem, of course, is that despite Googling for the syntax of making REST calls, and whether I used .NET’s WebClient, HttpWebRequest, or WebRequest classes, I kept on getting the same failure: a hang of a few minutes, followed by .NET throwing an exception with the message: “The underlying connection was closed: An unexpected error occurred on a send.”
This told me little, and pissed me off, and I was trying things left and right for at least 5 hours to no avail. What made it even crazier is that when I used RESTClient (as suggested by Radian6 support), I had zero problems connecting to the Radian6 API. So it was clearly something that I had to do in .NET to make this work. But what?
I only found the solution on my fourth page of Google results, on a post that is over 4 1/2 years old. It turns out that:
“…the defult behavior in Vista and Server 2008 is to use TLS first for secure connections. If the server doesn’t support TLS, it’s supposed to negotiate with the client to use SSL3. In this case, the remote server wasn’t negotiating at all…It was just dropping the connection.”
So clearly, the Radian6 servers are using SSL, my code was using TLS by default, and the Radian6 server does not renegotiate to use SSL. So the solution is merely to include the following ONE line of code, before the WebClient (or WebRequest or HttpWebRequest) is instantiated (so before line 3 in the code above). And that line of code is:
ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3;
That’s it. So simple, yet so impossible to find documented anywhere. Even 4 1/2 years after this post. Sheesh. Microsoft.
28 Responses to REST calls in .NET (C#) over SSL (HTTPS)
Leave a Reply Cancel reply
This site uses Akismet to reduce spam. Learn how your comment data is processed.
Recent Comments
- JPEREZGIL on REST calls in .NET (C#) over SSL (HTTPS)
- Reivaj810 on REST calls in .NET (C#) over SSL (HTTPS)
- Juancastein on Installing SharePoint 2013 on Windows Server 2012 R2 Preview
- Juancastein on Installing SharePoint 2013 on Windows Server 2012 R2 Preview
- Arjen Holterman on REST calls in .NET (C#) over SSL (HTTPS)
Categories
You have just saved my day…
I have spent like 4 hours before i found your post.
Thanks!
That’s why I try to blog these things. Glad I could help!
Big respect to you, you saved me too 🙂
Below – error descriptions on English and Russian, maybe this will help others to find this post.
ps: i’m using VB.Net Webclient()
System.Net.WebException: “The underlying connection was closed: An unexpected error occurred on a send.”
System.IO.IOException: “Authentication failed because the remote party has closed the transport stream.”
System.Net.WebException: “Базовое соединение закрыто: Непредвиденная ошибка при передаче.”
System.IO.IOException: “Проверка подлинности не пройдена из-за закрытия транспортного потока удаленной стороной.”
Thank you, thank you, thank you! I had been connecting to regular http rest api’s for several different websites without any issue, then I went and connected to one that was https instead, and kept getting the time you mentioned. Thank you for pointing this out, and helping me resolve my issue!
For it to work in VB, all I had to do was drop the ; at the end of the single line example.
Hey dude,
You saved my times. Thanks for this great post.
YAY AVIV! Grrrr Microsoft!
You have just saved me HOURS of work!
Thanks man!
Thanks a lot, sir.
Been working for 3 hours before I found this treasure.
Wish I could treat you with a beer!
one of the best answer man. 100 % correct.
It save my time.
Thanks
You sir are a prince among men, a prince. How can this be so under documented when it is so necessary!?!
Anyway, you saved my sanity and I thank you for that.
[…] connection before authentication could occur. After 2 days of researching on and off, I found this. The Kemp Load Balancer uses SSL3 but .Net always starts with TLS. AH HAA. The .Net to […]
Thank you! You are great!
Sweet! Very helpful, thanks.
Unbelievable! I have been banging my head against the wall. Thank you so much!
This is my code:
ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3;
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(“myurl”);
request.Method = “POST”;
request.KeepAlive = false;
request.ContentType = “application/x-www-form-urlencoded”;
request.UserAgent = “Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.2; SV1; CK={CVxk71YSfgiE6+6P6ftT7lWzblrdvMbRqavYf/6OcMIH8wfE6iK7TNkcwFAsxeChX7qRAlQhvPWso3KI6Jthvnvls9scl+OnAEhsgv+tuvs=}; .NET CLR 1.1.4322; .NET CLR 2.0.50727)”;
int pos = Request.Url.AbsoluteUri.LastIndexOf(‘/’);
// PAYMENT RESPONSE PAGE
string strURL = Request.Url.AbsoluteUri.Substring(0, pos + 1) + “xxx.aspx”;
string postData = “custacc=1234567890&login=” + ATOMLogin + “&pass=” + ATOMPassword”;
byte[] byteArray = Encoding.UTF8.GetBytes(postData);
request.ContentType = “application/x-www-form-urlencoded”;
request.ContentLength = byteArray.Length;
request.AllowAutoRedirect = true;
request.Proxy.Credentials = CredentialCache.DefaultCredentials;
Stream dataStream = request.GetRequestStream();
dataStream.Write(byteArray, 0, byteArray.Length);
dataStream.Close();
WebResponse response = request.GetResponse();
Still am getting Same Erro. pls help me
Error: The underlying connection was closed: An unexpected error occurred on a send.
..did you ever figure this out?… despite other saying the above article helped them.. I’m not having any such luck.
HELP!
la solucion esta en el web service no donde lo consumes
This works for me..
ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3 | SecurityProtocolType.Tls;
Thanks a lot. It solved my problem. But with a little correction. In my case i used not SecurityProtocolType.Ssl3 but SecurityProtocolType.Tls12
WOW,
This line was very helpfull!
ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3 | SecurityProtocolType.Tls;
Thanks!
Thanks Aviv! SecurityProtocolType.Ssl3; worked for me.
SecurityProtocolType.Ssl3 | SecurityProtocolType.Tls; did not work.
Thank you so much! This save me oodles of time.
THANK YOU SO MUCH!! Found this after wasting hours to make a simple REST call work and your article did the trick!!
ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3 | SecurityProtocolType.Tls12;
Just a note as lot of orgs are disabling TLS1.0 adding TLS12 did the magic for me – thanks again!!
Thank you all, this helped tremendously. Adding more info for others:
SSIS WebClient errors “Authentication failed because the remote party has closed the transport stream” and “The underlying connection was closed: An unexpected error occurred on a send.”
What helped me solve this issue after many hours of searching was this line (place it right before you create your webclient)
ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3 | SecurityProtocolType.Tls12;
For some reason just the .Tls would not work correctly.
You the best man… This made me climb over days of roadblocks. Thanks mwah
Thank you!
For me this worked.
ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3 | SecurityProtocolType.Tls12;
5 years later and this still holds true for Windows Server 2008 R2
6 years later and it stilll works ! Thanks.
Excelent post, but just in case that those don’t work, may be this can help us:
https://support.microsoft.com/en-us/help/3154518/support-for-tls-system-default-versions-included-in-the-net-framework
In my case I i had a APP whit 3.5 Net Framework and don’t have support for use tls 1.2
In the post of microsoft support you can find how fix this.
Thanks