PayPal PayFlowPro COMException 0x8000000A - vb.net

We have some code that runs to connect to PayPal's PayFlowPro to update a credit card used within a recurring billing subscription. This code used to work fine under a .Net 2 app pool, but when we migrated it to 4.0 it's very touchy - sometimes it works and other times it doesn't. The code seems pretty straightforward so I'm not sure what the issue is.
The error is: System.Web.HttpUnhandledException (0x80004005): Exception of type 'System.Web.HttpUnhandledException' was thrown. ---> System.Runtime.InteropServices.COMException (0x8000000A): The data necessary to complete this operation is not yet available.
The block of code that is intermittently failing (but used to work on an old server) is:
Try
objWinHttp = CreateObject("WinHttp.WinHttpRequest.5.1")
objWinHttp.Open("POST", GatewayHost, False)
objWinHttp.setRequestHeader("Content-Type", "text/namevalue") ' for XML, use text/xml
objWinHttp.SetRequestHeader("X-VPS-Timeout", "90")
objWinHttp.SetRequestHeader("X-VPS-Request-ID", requestID)
objWinHttp.Send(parmList)
Catch exc As Exception
End Try
' Get the text of the response. (DIES ON LINE BELOW)
transaction_response = objWinHttp.ResponseText
The confusing part is it works intermittently which is always hardest to debug. This is something that has existed for years and the only difference is our app pool is now running under .Net 4 vs. .Net 2.0, but I wouldn't think that would be an issue. I flipped it back to 2.0 and now it's working flawlessly though.
Any guesses on where to start looking? Does WinHttp.WinHttpRequest.5.1 have issues in .Net 4? The old server was 2008 R2 and the new one is 2012 R1 so perhaps that's part of it as well?
Update - changing to 2.0 still didn't fix it. It was working and then stopped again. This doesn't make any sense.

Since this was within inline .Net code (not compiled), I just migrated it to System.Net.HttpWebRequest instead which seems to be working much better. Here is sample code for anyone else hitting this:
Dim data As Byte() = New System.Text.ASCIIEncoding().GetBytes(parmList)
Dim request As System.Net.HttpWebRequest = CType(System.Net.HttpWebRequest.Create(GatewayHost), System.Net.HttpWebRequest)
request.Method = "POST"
request.ContentType = "text/namevalue"
request.ContentLength = data.Length
Dim requestStream As System.IO.Stream = request.GetRequestStream()
requestStream.Write(data, 0, data.Length)
requestStream.Close()
Dim responseStream = New System.IO.StreamReader(request.GetResponse().GetResponseStream())
transaction_response = responseStream.ReadToEnd()
responseStream.Close()

Related

System.Net.Sockets.SocketException, "The underlying connection was closed unexpectedly", but it works with open HTTPDebugger

So I communicate with a server of my company. I send data (to save in a *.csv file) and receive data (for version checking, just a string).
From one second to the other (without changing the code nor anything on the server side), I get this exception from my code:
"The underlying connection was closed unexpectedly. Error while sending data. -->" [...] "Data cant be read from the connection: An existing connection was closed by the remote host --->"
This is my code:
' Build data
' ...
' Create request and write data
Dim Agent As String = "> agent goes here <"
Dim Request As HttpWebRequest = DirectCast(HttpWebRequest.Create(Url), HttpWebRequest)
Request.UserAgent = Agent
Request.Method = "POST"
Request.ContentLength = outData.Length
Request.ContentType = "application/x-www-form-urlencoded"
Request.KeepAlive = False
Request.ProtocolVersion = HttpVersion.Version11 ' Fix 1
System.Net.ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3 ' Fix 2
Or SecurityProtocolType.Tls12
System.Net.ServicePointManager.Expect100Continue = True ' Fix 3
Request.Timeout = 1000000000 ' Fix 4
Request.ReadWriteTimeout = 1000000000 ' Fix 5
Request.ClientCertificates.Add(New X509Certificate()) ' Fix 6
Using Stream As IO.Stream = Request.GetRequestStream ' Exception still gets thrown here
Stream.Write(outData, 0, outData.Length)
End Using
As you can see, I already tried many different ways to fix (and to be honest, I dont really know what I do, I still need to get more knowledge in this field)
The interesting thing is, when I start my HTTPDebugger, the error does not occur and I have no problems at all, everything works just fine.
So my guess is that the HTTPDebugger somehow installs/intercepts with a certain certificate which I dont know and then the server accepts the connection again.
But how can I provide such a certificate, where to get it, and which should I use. And if thats not the problem: What could it be?
Turns out that updating from .NET 4.5 to .NET 4.7.2 and compiling again solved the problem.
I dont know why this problem happened and how it could have been solved otherwise, but this fixed it for me.

Invalid Session ID from SalesForce REST API

I'm making a call to the SalesForce REST Api.
However, I have a very weird error. Initially I wrote this in a VB.NET Module file. Everything was working correctly, as soon as I put the method in a class I keep getting the darn Invalid Session ID error. The error doesn't seem to suggest which part of the code is failing.
I am using RestSharp to facilitate the call to the SalesForce API, and I know for a fact it works because in the Module file I am able to fetch the data that I need.
I do not understand the rationale about why it works in the Module file but not in a class file.
Anyways, here is the code that I've placed in both the class file and the Module file to facilitate the call:
client = New RestClient(_strURI)
request = New RestRequest(Method.POST)
request.AddParameter("grant_type", "password")
request.AddParameter("client_id", _strClientID)
request.AddParameter("client_secret", _strClientSecret)
request.AddParameter("redirect_uri", _strRedirectUrl)
request.AddParameter("username", _strUserName)
request.AddParameter("password", _strPassword & _strSecurityToken)
'Dim response As IRestResponse
Dim response As IRestResponse = Nothing
response = client.Execute(request)
'This is the offending line in the class file..it returns back a HTTP 200 yet gives me that Session Invalid error
If response.StatusCode <> HttpStatusCode.BadRequest Then
token = JsonConvert.DeserializeObject(Of TokenResponse)(response.Content)
Dim listViewResults As String = HttpGet(token.instance_url & "/services/data/v38.0/sobjects/Contact/listviews", "")
I am unsure whether this is a permission issue or more of a programming error; because in both cases all of the authentication strings are the same. At the moment I've hardcoded it to point to a test profile. So I can't pinpoint what exactly I am doing wrong?
Any help would suffice.
Stupid me,
Anyways shortly after I posted this I went and took a brisk walk outside of the office. Turned out to be a misnomer.
I had the same HttpGet method defined in the module file and forgot to copy and paste that into the class file. When I actually stepped through it, it threw an Exception inside.
Turned out the only fix needed was to put that method into the class file.

WordPress Post Scraper visual basic

I need following. I need to scrape posts from mine WordPress blog and show them in VB application. But news must be fresh, when user clicks "Refresh" it gets new content from website. So, posts from first page and link to it.
Any way to do this? Is that even possible?
This is very possible and I will give you three possible solutions.
The first solution is to use Telerik's (free!) Testing Framework http://www.telerik.com/teststudio/testing-framework. It is meant to be used for testing your website for flaws and whatnot but it makes for an excellent scraper. Once you get to know how to use the syntax this is most likely the fastest and easiest solution but it also has the most overhead. It uses browser addons to allow you to "control" Mozilla Firefox, Google Chrome, Apple Safari and Microsoft Internet Explorer. The main disadvantage with this one is that you must install the setup package on all computers that you wish to use this on. If you are only building a simple scraper to get data from your own blog and you will only run this on one machine this is probably the best way to go.
The next scraper I will mention is called Watin and you can get it from http://watin.org/. I personally prefer this one to Telerik's because it only requires a few dlls to be included in your project and once deployed it works great on another machine without having to install any special software. Unfortunately there are a few caveats as well. The big issue is that it hasn't been updated since 2011 so I'm assuming the project is dead, although the website still exists. Because of the lack of updates it officially only supports Internet Explorer 6, 7, 8, 9 and FireFox 2 and 3 (But I can vouch for it working fine in IE 10 + 11 on Windows 7+8). The syntax is a bit more wonky than Teleriks but it should be easy enough to use for what you need it for.
The last option that I can recommend is to use the HttpWebRequest and HttpWebResponse classes built into DotNet and do your scraping manually. I will admit that I still use this approach on occasion. It basically just brings back the source code for a certain url and you have to use string manipulation (or regex if you are good at that) to pull out the information you need. The upside to this one is that it has the least overhead as it requires no extra dlls or installs to work, and it's very fast. I will provide you a sample function that I have used and reused in a number of projects to pull data from the web:
Private Function GetMethod(ByVal sPage As String) As String
Dim req As HttpWebRequest
Dim resp As HttpWebResponse
Dim stw As StreamReader
Dim sReturnString As String = ""
Dim sUserAgent As String = "Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; WOW64; Trident/6.0)"
Try
req = HttpWebRequest.Create(sPage)
req.Method = "GET"
req.AllowAutoRedirect = False
req.UserAgent = sUserAgent
req.Accept = "text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5"
req.Headers.Add("Accept-Language", "en-us,en;q=0.5")
req.Headers.Add("Accept-Charset", "ISO-8859-1,utf-8;q=0.7,*;q=0.7")
req.Headers.Add("Keep-Alive", "300")
req.KeepAlive = True
resp = req.GetResponse ' Get the response from the server
If req.HaveResponse Then
resp = req.GetResponse ' Get the response from the server
stw = New StreamReader(resp.GetResponseStream)
sReturnString = stw.ReadToEnd() ' Save the source code of the url into a string
Else
MessageBox.Show("No response received from host " & sPage, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
End If
Catch exc As WebException
MessageBox.Show("Network Error: " & exc.Message.ToString & " Status Code: " & exc.Status.ToString & " from " & sPage, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
End Try
Return sReturnString
End Function
Just a note about the sUserAgent variable: You can change this to any user agent you want to emulate. In this case I am using Mozilla Firefox 5 which is obviously super old but I have been using this function for years and haven't needed to update it.

FtpWebResponse GetResponse() gives "The remote server returned an error: (550) File unavailable (e.g., file not found, no access)."

I have a Win Form with a picture gallery that uses FtpWebRequest to upload pictures, but after changing to .Net 4.0 I suddenly get 550 error. The error occurs both when uploading files and listing directory.
As seen in my example-code I have implemented the MS solution from http://support.microsoft.com/kb/2134299.
I have checked the username, password and path - everything is correct.
Still, I get an error. I have skimmed Google for every solution without any response.
SetMethodRequiredCWD();
FtpWebRequest reqFTP = (FtpWebRequest)WebRequest.Create(new Uri(pPath));
reqFTP.Credentials = new NetworkCredential(Properties.Settings.Default.FTPUser, Properties.Settings.Default.FTPPass);
reqFTP.Method = WebRequestMethods.Ftp.ListDirectory;
reqFTP.KeepAlive = false;
FtpWebResponse respFTP = (FtpWebResponse)reqFTP.GetResponse();
Stream respStreamFTP = respFTP.GetResponseStream();
StreamReader streamReader = new StreamReader(respStreamFTP, Encoding.Default);
One approach I would recommend is to monitor the request/response exchange between the ftp-client and -server using e.g. Fiddler.
First, record a session in which the error does not manifest by manually using a third party client such as Filezilla to upload the file. Then, record another session with your program as the client. Comparing the exchanged messages may yield some insight to what is wrong.
Try to enable Network Tracing: http://msdn.microsoft.com/en-us/library/a6sbz1dx%28v=vs.100%29.aspx

VB.NET HTTP LAG! Trying to make an IM client on my own

I have recently developed and finished a software in which works like aim.
But here's the problem, the server worked just fine for local friends because they lived only 25 miles from the server, so it was lag-less.
But when uploaded to a web host, it lags every time it pings the server.
The server is in PHP, so there's no need to buy a dedicated computer for 400$/month more.
Here's the function in which the client constantly calls upon:
Public Function GetPage(ByVal url As String)
Dim WReq As HttpWebRequest
Dim WResp As WebResponse
Dim sr As IO.StreamReader
Try
WReq = WebRequest.Create(url)
WReq.CookieContainer = cookies
WReq.Timeout = "120000"
WResp = WReq.GetResponse()
sr = New IO.StreamReader(WResp.GetResponseStream())
GetPage = sr.ReadToEnd()
WResp.Close()
Return (GetPage)
Catch err As SystemException
MsgBox("err message: " & err.ToString & vbCrLf)
Catch ex As Exception
MsgBox("err message: " & ex.ToString & vbCrLf)
End Try
End Function
A demo url would be something like
http://localhost/chat/newpm.php?to=User&msg=Hello
So how does OSCAR do it (the platform for AOL, aka AIM)
and how does msg? gtalk or other big im clients do it?
I was thinking about recoding the getpage function so that it would connect to a TCP server and constantly wait for new messages which I am still not sure if this might cause a lag if the host is in the US and the client is not(for example).
Could you please provide me a remedy to this problem?
The Timeout is really high. Check if the app closes the connection after receive the response stream. How many aconnections the computer accepts otherwise the connectios will lock the request until one goes free.
Ok to answer John Feminella:
Exactly I agreee, how does AIM MSN and others solve this hang issue?
Dbasnett: return(GetPage) will return the result of the requested page, and this is just the main snipppet of the code which is called every second at least two times.
John Saunders:
I don't understand the purpose or function of the "using" blocks, I added the catch so that the user is not notified when the server times out or can't be resolved.
Sein Kraft:
Time out is only 2 minutes, i don't think it does
GetPage(Login.server & "pms.php?to=" & to)
That's all, then it would parse the results from the response.