asp.net vb socket works on first iteration only - asp.net

I have a server used to get info from SAPGUI. Everything works fine for a first request but nothing after that. The first iteration waits for a socket event. Once the socket is read for the first time it just loops without reading the receive buffer. I am assuming I need to reset the listener but am having trouble doing so.
'first iteration it works as expected but readbyte is always 0 after that even though it loops through fine.
'what I don't get is that the first iteration it waits for data to come down the socket, but after that it just loops
'and doesn't retreive anything.
Dim listenerSocket As Socket = New Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)
Dim ipend As IPEndPoint = New IPEndPoint(IPAddress.Parse("127.0.0.1"), 8888)
listenerSocket.Bind(ipend)
listenerSocket.Listen(0)
Dim clientSocket As Socket = listenerSocket.Accept()
Dim Buffer As Byte() = New Byte(clientSocket.SendBufferSize - 1) {}
Dim readByte, sendByte As Integer
Dim Sbuffer As Byte() = System.Text.Encoding.ASCII.GetBytes("Some form of SAP response!")
Dim clientError As System.Net.Sockets.SocketError
Console.WriteLine("Waiting for connection : ")
For infinitecounter = 1 To 3
infinitecounter = 1
readByte = clientSocket.Receive(Buffer)
While (True)
If readByte > 0 Then
Dim rData As Byte() = New Byte(readByte - 1) {}
Array.Copy(Buffer, rData, readByte)
SAPrq = System.Text.Encoding.UTF8.GetString(rData)
SAPpar = Left(SAPrq, 1)
SAPpar1 = InStr(SAPrq, "%")
If SAPpar = 1 Then
SAPnwk = Mid(SAPrq, 3)
xy = Getbam(SAPnwk)' this is a function that talks to SAP and it works on first loop
End If
End if
End While
Next
I tried adding setting infinitecounter = 2 before the next statement and adding an if statement to reset the listener but failed.

Related

Problems With Paypal Express Checkout Integration (WEBREQUEST)

So I was struggling with making head or tail out of the PayPal documentation and always felt that something was not right with my Webrequest.
So I stripped all the code back to basic and simply submitted the request via HTTP and the PLUS side is that I now get a response back from the PayPal sandbox server where ACK=Success and TOKEN=Valid-token-value-here there are some other variables returned too, such as CORRELATIONID and TIMESTAMP.
And hence so I tried some of the webrequest samples and I simply get a blank screen instead of being redirected to Paypal for the (sandbox) customer to complete payment.
So if anyone can post their WebRequest method that would be great.
Here is the code I used for my webrequest, I'm sure its wrong but cannot pinpoint where it is going wrong.
Also, when I run the code on my localhost during debugging, everything works fine and the call is completed with SUCCESS and a TOKEN is received.
When I run it live, I recieve Error Number 5 in the Error exception and also the text `Remote host failed to connect' in the STATUS DESCRIPTION.
THIS IS THE UPDATED CODE
Function MakeWebRequest(ByVal pUseSandbox As Boolean, ByVal pRequestMethod As String, ByVal pReturnUrl As String, ByVal pCancelUrl As String, ByRef pRtnStatus As String, ByRef pRtnStatusId As HttpStatusCode, ByRef pRtnResponseString As String) As Boolean
'
Dim _sxHost As String = Nothing
Dim _sxEndpoint As String = Nothing
Dim _sxNameValCol As System.Collections.Specialized.NameValueCollection = Nothing
Dim _sxResponseCol As System.Collections.Specialized.NameValueCollection = Nothing
Dim _sxCounta As Integer = Nothing
Dim _sxParamsString As String = Nothing
'
'-> Init
_sxParamsString = ""
MakeWebRequest = False
_sxNameValCol = New System.Collections.Specialized.NameValueCollection()
_sxResponseCol = New System.Collections.Specialized.NameValueCollection()
If pUseSandbox Then
_sxHost = "http://www.sandbox.paypal.com"
_sxEndpoint = "https://api-3t.sandbox.paypal.com/nvp"
Else
_sxHost = "http://www.paypal.com"
_sxEndpoint = "https://api-3t.paypal.com/nvp"
End If
'-> Create Request
Try
'-> Key/Value Collection Params
_sxNameValCol.Add("METHOD", "SetExpressCheckout")
_sxNameValCol.Add("USER", _UserName)
_sxNameValCol.Add("PWD", _Password)
_sxNameValCol.Add("SIGNATURE", _Signature)
_sxNameValCol.Add("PAYMENTREQUEST_0_AMT", Format(_Basket.BasketTotalIncDelivery / 100, "0.00"))
_sxNameValCol.Add("PAYMENTREQUEST_0_PAYMENTACTION", "Sale")
_sxNameValCol.Add("PAYMENTREQUEST_0_CURRENCYCODE", "GBP")
_sxNameValCol.Add("RETURNURL", pReturnUrl)
_sxNameValCol.Add("CANCELURL", pCancelUrl)
_sxNameValCol.Add("REQCONFIRMSHIPPING", "0")
_sxNameValCol.Add("NOSHIPPING", "2")
_sxNameValCol.Add("LOCALECODE", "EN")
_sxNameValCol.Add("BUTTONSOURCE", "PP-ECWizard")
_sxNameValCol.Add("VERSION", "93.0")
'-> UrlEncode
For _sxCounta = 0 To _sxNameValCol.Count - 1
If _sxCounta = 0 Then
_sxParamsString = _sxParamsString & _sxNameValCol.Keys(_sxCounta) & "=" & HttpUtility.UrlEncode(_sxNameValCol(_sxCounta))
Else
_sxParamsString = _sxParamsString & "&" & _sxNameValCol.Keys(_sxCounta) & "=" & HttpUtility.UrlEncode(_sxNameValCol(_sxCounta))
End If
Next
'-> Credentials (not used)
'_sxRequest.Credentials = CredentialCache.DefaultCredentials
Try
Dim _sxRequest As WebRequest = DirectCast(System.Net.WebRequest.Create(_sxEndpoint), System.Net.HttpWebRequest)
'-> Convert request to byte-array
Dim _sxByteArray As Byte() = Encoding.UTF8.GetBytes(_sxParamsString)
_sxRequest.Method = "POST" 'Our method is post, otherwise the buffer (_sxParamsString) would be useless
_sxRequest.ContentType = "application/x-www-form-urlencoded" 'We use form contentType, for the postvars
_sxRequest.ContentLength = _sxByteArray.Length 'The length of the buffer (postvars) is used as contentlength
Dim _sxPostDataStream As System.IO.Stream = _sxRequest.GetRequestStream() 'We open a stream for writing the postvars
_sxPostDataStream.Write(_sxByteArray, 0, _sxByteArray.Length) 'Now we write, and afterwards, we close
_sxPostDataStream.Close() 'Closing is always important!
'-> Create Response
Dim _sxResponse As HttpWebResponse = DirectCast(_sxRequest.GetResponse(), HttpWebResponse)
'-> Get Response Status
pRtnStatus = _sxResponse.StatusDescription
pRtnStatusId = _sxResponse.StatusCode
'-> Reponse Stream
Dim _sxResponseStream As Stream = _sxResponse.GetResponseStream() 'Open a stream to the response
'-> Response Stream Reader
Dim _sxStreamReader As New StreamReader(_sxResponseStream) 'Open as reader for the stream
pRtnResponseString = _sxStreamReader.ReadToEnd() 'Read the response string
MakeWebRequest = True
'-> Tidy up
_sxStreamReader.Close()
_sxResponseStream.Close()
_sxResponse.Close()
_sxByteArray = Nothing
_sxPostDataStream = Nothing
_sxRequest = Nothing
_sxResponse = Nothing
_sxResponseStream = Nothing
_sxStreamReader = Nothing
Catch ex As Exception
pRtnStatusId = Err.Number
pRtnStatus = "response(" & ex.Message & ")"
Decode(pRtnResponseString, _sxResponseCol)
pRtnResponseString = Stringify(_sxResponseCol)
End Try
Catch ex As Exception
pRtnStatusId = Err.Number
pRtnStatus = "request(" & ex.Message & ")"
Decode(pRtnResponseString, _sxResponseCol)
pRtnResponseString = Stringify(_sxResponseCol)
End Try
'-> Tidy Up
_sxHost = Nothing
_sxEndpoint = Nothing
_sxNameValCol = Nothing
_sxResponseCol = Nothing
_sxCounta = Nothing
_sxParamsString = Nothing
'
End Function
OK, so it's now clear that you're not getting any response from the server because your server isn't able to connect to PayPal's servers at all. Hence, you got no server-response and the message Unable to connect to the remote server. When I tested, I got a HTTP 200 response with the following body:
TIMESTAMP=2015-07-07T09:07:39Z&CORRELATIONID=7f4d2313c9696&ACK=Failure&VERSION=93.0&BUILD=17276661&L_ERRORCODE0=10002&L_SHORTMESSAGE0=Authentication/Authorization Failed&L_LONGMESSAGE0=You do not have permissions to make this API call&L_SEVERITYCODE0=Error
Obviously that's because I tested with a blank username and password.
So, something is wrong with your server setup that's preventing you from making outside connections, either at the IIS level or due to your firewall configuration.
Without physically being present at your machine, there's not a lot we can do to track down what's blocking it, but you can try opening HTTP requests to other public websites like Google.com and see if those succeed.

Connection property has not been initialized when filling a DataSet

So here is my issue:
Currently I am trying to make a report that will show 1st and 2nd shifts, by multiple days...
So if they select the range 6/02 - 6/04, I am running a query 3 times... once for 6/02, 6/03, and 6/04... Also they can select shift, so it would be those dates, but 4:30AM-4:30PM for 1st shift....
Currently I have a error, when trying to put my queries/calls inside the for loop... I calculate the difference of the two dates and set them up fine, its just my connection string gives me the error:
If the image is not easy to see here is a text description of the error:
Server Error in '/mfgx_test' Application.
Fill: SelectCommand.Connection property has not been initialized.
Description: An unhandled exception occurred during the execution of
the current web request. Please review the stack trace for more
information about the error and where it originated in the code.
Exception Details: System.InvalidOperationException: Fill:
SelectCommand.Connection property has not been initialized.
Source Error:
Line 623: Dim dsTop1 As New DataSet Line 624: Dim daTop1
As New SqlDataAdapter(strSql, myCn1) Line 625:
daTop1.Fill(dsTop1) Line 626: Line 627: myCn1.Close()
Source File: C:\inetpub\wwwroot\mfgx_test\defectsbyround.aspx.vb
Line: 625
Which leads me to beleive that something is wrong with my connection string being outside of my for loop... My code is as follows (Although a bit cleaned up so it is easier to read):
Dim myCn1 As New SqlConnection
myCn1.ConnectionString = "server=Blah;database=Blah;user id=Blah;password=Blah"
myCn1.Open()
For i = 0 To Session("DaysDiff")
strSql = "Blah.Blah"
Dim dsTop1 As New DataSet
Dim daTop1 As New SqlDataAdapter(strSql, myCn1)
daTop1.Fill(dsTop1)
myCn1.Close()
myCn1 = Nothing
If dsTop1.Tables(0).Rows.Count > 0 Then
spitout2(dsTop1)
End If
txtStartdate.Text = DateAdd("d",1,txtStartdate.Text)
txtEnddate.Text = DateAdd("d",1,txtEnddate.Text)
Next
That's because you are closing the connection inside your loop and so for next iteration there is no open connection present and hence the exception (see pointed below)
myCn1.Close()
myCn1 = Nothing
You should declare the Dataset and tableadapter as well out side the loop context. Your code should somewhat look like below
Dim myCn1 As New SqlConnection
myCn1.ConnectionString = "server=Blah;database=Blah;user id=Blah; password=Blah"
myCn1.Open()
Dim dsTop1 As New DataSet
Dim daTop1
For i = 0 To Session("DaysDiff")
strSql = "Blah.Blah"
daTop1 As New SqlDataAdapter(strSql, myCn1)
daTop1.Fill(dsTop1)
.......
Next
myCn1.Close()
myCn1 = Nothing
Assuming you want to reuse the connection inside the loop, release the connection automatically with a Using statement outside the for loop
Using myCn1 As New SqlConnection("server=Blah;database=Blah;user id=Blah;password=Blah")
myCn1.Open()
For i = 0 To Session("DaysDiff")
strSql = "Blah.Blah"
Dim dsTop1 As New DataSet
Dim daTop1 As New SqlDataAdapter(strSql, myCn1)
daTop1.Fill(dsTop1)
If dsTop1.Tables(0).Rows.Count > 0 Then
spitout2(dsTop1)
End If
txtStartdate.Text = DateAdd("d",1,txtStartdate.Text)
txtEnddate.Text = DateAdd("d",1,txtEnddate.Text)
Next
End Using
When End Using is reached, SqlConnection.Dispose() will be called, releasing connection resources.

Export Crystal Report to PDF in a Loop only works with first

i'm trying to generate a report and export it to pdf in a loop, the report will receive a new parameter in each loop and prompt the client to download a PDF, in other words, the client may need to download 2 or 3 (or more) PDFs at the same time, the problem is that the prompt to accept the download only appears for the first pdf, dont know why. I can export to disk (server side) without any problems.
Code:
Sub PrintReport(ByVal Cod As Integer)
Dim CTableLogInfo As TableLogOnInfo
Dim ConnInfo As CrystalDecisions.Shared.ConnectionInfo = New ConnectionInfo()
ConnInfo.Type = ConnectionInfoType.SQL
ConnInfo.ServerName = ConfigurationManager.AppSettings("SQLSERVERNAME")
ConnInfo.DatabaseName = ConfigurationManager.AppSettings("SQLDBNAME")
ConnInfo.UserID = ConfigurationManager.AppSettings("SQLSERVERUSER")
ConnInfo.Password = ConfigurationManager.AppSettings("SQLSERVERPASSWORD")
ConnInfo.AllowCustomConnection = False
ConnInfo.IntegratedSecurity = False
For Each CTable As Table In CrystalReportSource1.ReportDocument.Database.Tables
CTable.LogOnInfo.ConnectionInfo = ConnInfo
CTableLogInfo = CTable.LogOnInfo
CTableLogInfo.ReportName = CrystalReportSource1.ReportDocument.Name
CTableLogInfo.TableName = CTable.Name
CTable.ApplyLogOnInfo(CTableLogInfo)
Next
Dim pField As ParameterField = CrystalReportSource1.ReportDocument.ParameterFields(0)
Dim val1 As ParameterDiscreteValue = New ParameterDiscreteValue
val1.Value = Cod
pField.CurrentValues.Clear()
pField.CurrentValues.Add(val1)
Dim PDFName As String = "PDF Nº " & Cod
CrystalReportSource1.ReportDocument.ExportToHttpResponse(ExportFormatType.PortableDocFormat, Page.Response, True, PDFName)
End Sub
EDIT:
Tried to zip the reports with DotNetZip but i get an broken zip.
Can you tell me whats wrong? (Solved: code bellow is corrected now)
Response.ClearContent()
Response.ClearHeaders()
Response.ContentType = "application/zip"
Response.AppendHeader("content-disposition", "attachment; filename=AllPDFs.zip")
Using zipFile As New ZipFile()
For i = 0 To Cod.Length - 1
If Cod(i) > 0 Then
val1.Value = Cod(i)
pField.CurrentValues.Clear()
pField.CurrentValues.Add(val1)
val2.Value = Cod(i)
pField2.CurrentValues.Clear()
pField2.CurrentValues.Add(val2)
Dim PDFNameAs String = "PDF Nº " & Cod(i) & ".pdf"
Dim s As New System.IO.MemoryStream
s =CrystalReportSource1.ReportDocument.ExportToStream(ExportFormatType.PortableDocFormat)
zipFile.AddEntry(PDFName, s)
End If
Next
zipFile.Save(Response.OutputStream)
End Using
Response.Clear()
Probably the response ends after the first one, therefore there's no response to write to for the 2nd and 3rd attempts.
Instead, you can have the client download the reports via AJAX Request (move your report generation into an .ashx generic handler), or have the user click the button 3 times to initiate new requests.
Or zip the PDF's up until a single file and allow the client to download that.

Fixing a directX function which gets the video length in VB.NET

I have found a function which invokes Microsoft.DirectX.AudioVideoPlayback to get the length of a video file.
Here is that code:
`Private Function GetVideoInformation(ByVal videoFilePath As String) As VideoInfo
Try
If My.Computer.FileSystem.FileExists(videoFilePath) Then
Dim videoToGetInfoOn As Microsoft.DirectX.AudioVideoPlayback.Video
videoToGetInfoOn = New Microsoft.DirectX.AudioVideoPlayback.Video(videoFilePath)
Dim atpf As Double = videoToGetInfoOn.AverageTimePerFrame
Dim vidSize As New Size
vidSize = videoToGetInfoOn.Size
Dim thisVideoInfo As New VideoInfo
thisVideoInfo.videoWidth = vidSize.Width
thisVideoInfo.videoHeight = vidSize.Height
thisVideoInfo.videoDuration = videoToGetInfoOn.Duration
If videoToGetInfoOn.Duration > 0 Then
defaultLength = videoToGetInfoOn.Duration
End If
If atpf > 0 Then
thisVideoInfo.videoFps = 1 / atpf
Else
thisVideoInfo.videoFps = 0
End If
Return thisVideoInfo
Else
Throw New Exception("Video File Not Found" & vbCrLf & vbCrLf & videoFilePath)
Return Nothing
End If
Catch ex as Exception
msgbox(ex.message)
End Try
End Function`
I have a timer that calls this function once on 2 seconds to check many videos, and the app works fine for the first 10 videos or so. After that, it throws
"Error in application"
message instead.
In general, things from DirectShow/DirectX MUST be disposed of in the way the docs require or this sort of thing happens. Here, you are creating videoToGetInfoOn objects but never releasing them.
You need to explicitly release all the resources you and it allocated with videoToGetInfoOn = Nothing before your procedure exits. Try that.
I will add that MediaInfo.DLL can be used to get everything from a media file without the overhead of Dx. There is a commandline version that you might be able to read from reading stdout.
I got it working.
The code needs a dispose method.
Here is the final code:
`Private Function GetVideoInformation(ByVal videoFilePath As String) As VideoInfo
Try
If My.Computer.FileSystem.FileExists(videoFilePath) Then
Dim videoToGetInfoOn As Microsoft.DirectX.AudioVideoPlayback.Video
videoToGetInfoOn = New Microsoft.DirectX.AudioVideoPlayback.Video(videoFilePath)
Dim atpf As Double = videoToGetInfoOn.AverageTimePerFrame
Dim vidSize As New Size
vidSize = videoToGetInfoOn.Size
Dim thisVideoInfo As New VideoInfo
thisVideoInfo.videoWidth = vidSize.Width
thisVideoInfo.videoHeight = vidSize.Height
thisVideoInfo.videoDuration = videoToGetInfoOn.Duration
If videoToGetInfoOn.Duration > 0 Then
defaultLength = videoToGetInfoOn.Duration
End If
If atpf > 0 Then
thisVideoInfo.videoFps = 1 / atpf
Else
thisVideoInfo.videoFps = 0
End If
videoToGetInfoOn.Dispose() 'this line here needed to be added
Return thisVideoInfo
Else
Throw New Exception("Video File Not Found" & vbCrLf & vbCrLf & videoFilePath)
Return Nothing
End If
Catch ex as Exception
msgbox(ex.message)
End Try
End Function`

Response.Redirect a download in progress

I have a website where a user can choose to view a video (no copyright) that is on a 3rd party website. From the moment the user choose it, it needs to be downloaded onto my web server before the user can access it. I tried to automatically start the download on the 3rd party website and make a response.redirect with this path, but when the user is watching the video, if the video has only 10 seconds downloaded, any player/browser will considere this video as a ten-seconds video and stop it after 10 seconds.
What would be the best practice to redirect a stream instead of a file?
I found that this piece of code is doing exactly what I want. It downloads a file on a third party website, and as it's streaming it, each chunk is writen in the Response so that it completely obsfuscates the origin. Thus, it is possible to serve any file from any website as if I own it.
Private Sub SendFile(ByVal url As String)
Dim stream As System.IO.Stream = Nothing
Dim bytesToRead As Integer = 10000
Dim buffer() As Byte = New Byte((bytesToRead) - 1) {}
Try
Dim fileReq As System.Net.WebRequest = CType(System.Net.HttpWebRequest.Create(url), System.Net.HttpWebRequest)
Dim fileResp As System.Net.HttpWebResponse = CType(fileReq.GetResponse, System.Net.HttpWebResponse)
If (fileReq.ContentLength > 0) Then
fileResp.ContentLength = fileReq.ContentLength
End If
stream = fileResp.GetResponseStream
Dim resp As System.Web.HttpResponse = HttpContext.Current.Response
resp.ContentType = "application/octet-stream"
resp.AddHeader("Content-Disposition", ("attachment; filename=\""" + ("mp3" + "\""")))
resp.AddHeader("Content-Length", fileResp.ContentLength.ToString)
Dim length As Integer = 1000000
While (length > 0)
If resp.IsClientConnected Then
length = stream.Read(buffer, 0, bytesToRead)
resp.OutputStream.Write(buffer, 0, length)
resp.Flush()
buffer = New Byte((bytesToRead) - 1) {}
Else
length = -1
End If
End While
Catch
stream.Close()
Finally
If (Not (stream) Is Nothing) Then
stream.Close()
End If
End Try
Response.End()
End Sub

Resources