FTP UPLOAD to AS/400 from VB.NET - vb.net

I am attempting to perform a FTP Put function to an AS/400 IBM Mainframe with VB.NET. I am able to upload a file however, I need to be able to capture each output response from the mainframe for logging purposes. In short capture what prints out on the cmd screen if I were to perform the FTP manually. Any suggestions would be greatly appreciated.

Depending on the library you are using, you should be able to get some kind of response object or string from the FTP server for each command you submit. You can then parse these responses and dump them into a file/destination/source of your choosing.
EDIT: Since you're using the FTPWebRequest/Response library, you'll want to have your FTPWebRequest object dump its results into the FTPWebResponse object and then read the entire stream with code something like this:
Dim request As FtpWebRequest = DirectCast(WebRequest.Create(serverUri), FtpWebRequest)
request.Method = WebRequestMethods.Ftp.ListDirectory
Dim response As FtpWebResponse = DirectCast(request.GetResponse(), FtpWebResponse)
Dim responseStream As Stream = Nothing
Dim readStream As StreamReader = Nothing
Try
responseStream = response.GetResponseStream()
readStream = New StreamReader(responseStream, System.Text.Encoding.UTF8)
If readStream IsNot Nothing Then
Console.WriteLine(readStream.ReadToEnd())
End If
Console.WriteLine("List status: " & response.StatusDescription)
Finally
If readStream IsNot Nothing Then
readStream.Close()
End If
If response IsNot Nothing Then
response.Close()
End If
End Try
Return True
End Function
You should be able to tailor this code to your own in order to retrieve the response details you need.

Related

Why would my VB.NET WebRequest suddenly stop working?

A while ago I wrote a programme in VB.NET to use the Betfair Exchange API. It has worked perfectly for months, but overnight on Tuesday it stopped working. I can still log in, but from Wednesday I have been unable to get anything else from the server.
Betfair are investigating, but according to them nobody else seems to be experiencing the same problem - although I'm not sure how many will be using VB.NET.
Below is the function I have been using to obtain data from the API. Like I said it was working on Tuesday night but not from Wednesday morning. Is there anything here which is "not perfect" or "could be better", or perhaps there is some alternative code I could try? Or is there something which might have happened on my pc which has caused the problem?
The programme falls over at the line "dataStream = request.GetRequestStream() ". The error is "Received an unexpected EOF or 0 bytes from the transport stream."
I would be grateful for any advice that anyone could offer. Thank you!
Public Function CreateRequest(ByVal postData As String, Optional ByVal accountsApi As Boolean = False)
Dim Url As String = "https://api.betfair.com/exchange/betting/json-rpc/v1"
If accountsApi Then Url = "https://api.betfair.com/exchange/account/json-rpc/v1"
Dim request As WebRequest = Nothing
Dim dataStream As Stream = Nothing
Dim response As WebResponse = Nothing
Dim strResponseStatus As String = ""
Dim reader As StreamReader = Nothing
Dim responseFromServer As String = ""
Try
request = WebRequest.Create(New Uri(Url))
request.Method = "POST"
request.ContentType = "application/json-rpc"
request.Headers.Add(HttpRequestHeader.AcceptCharset, "ISO-8859-1,utf-8")
request.Headers.Add("X-Application", appKey)
request.Headers.Add("X-Authentication", sessToken)
Dim byteArray As Byte() = Encoding.UTF8.GetBytes(postData) ' Data to post such as ListEvents, ListMarketCatalogue etc
request.ContentLength = byteArray.Length ' Set the ContentLength property of the WebRequest.
dataStream = request.GetRequestStream() ' Get the request stream.
dataStream.Write(byteArray, 0, byteArray.Length) ' Write the data to the request stream.
dataStream.Close() ' Close the Stream object.
response = request.GetResponse() ' Get the response.
strResponseStatus = CType(response, HttpWebResponse).StatusDescription ' Display the status below if required
dataStream = response.GetResponseStream() ' Get the stream containing content returned by the server.
reader = New StreamReader(dataStream) ' Open the stream using a StreamReader for easy access.
responseFromServer = reader.ReadToEnd() ' Read the content.
reader.Close() : dataStream.Close() : response.Close()
Catch ex As Exception
MsgBox("CreateRequest Error" & vbCrLf & ex.Message, MsgBoxStyle.Critical, " Error")
End Try
Return responseFromServer
End Function
I would check that the provider hasn't recently deprecated use of TLS 1.0 (as they should have done before now, in fact).
If so, your code needs to enforce use of TLS 1.1+:
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12;
This only has to be set once, usually in the (static) type initializer or similar.
And I 100% agree with Andrew Mortimer that you should use Using blocks wherever possible. I'd also suggest moving all of your string values into variables or constants to clean things up and keep them maintainable. Eg:
Const ContentType As String = "application/json-rpc"
...
request.ContentType = ContentType
UPDATE
I just found this announcement on their site:
https://forum.developer.betfair.com/forum/developer-program/announcements/33563-tls-1-0-no-longer-supported-from-1st-december-all-betfair-api-endpoints
If you are allowed to use external dependencies within this project I would recommend using RestSharp nuget package it works really well for creating API requests and getting there response without having to use httpclient which gets messy.
Link: https://restsharp.dev/

Checking the length of a stream

So i have written code to allow me to download files from an FTP server using the system.io.stream function in vb.net. Now I need to be able to find the length of the stream, when i has finished.
I have worked with streamreader in the past but this stream doesn't work in the same way so i'm not sure how to proceed.
Try
Dim request As System.Net.FtpWebRequest
request = DirectCast(System.Net.WebRequest.Create("ftp://ftp.server.com/Folder/" & FileName & ".pdf"), System.Net.FtpWebRequest)
request.Credentials = New System.Net.NetworkCredential("Username", "Password")
request.Method = System.Net.WebRequestMethods.Ftp.DownloadFile
Dim stream As System.IO.Stream = request.GetResponse.GetResponseStream
'Dim OutPutFilepath As String = "DownloadTest" & "\" & IO.Path.GetFileName("ftp://ftp.Server.com/Folder/")
output = System.IO.File.Create("C:\Users\ASUS\Documents\TestFile2.pdf")
output.Close()
stream.Close()
Console.WriteLine("Downloaded")
Console.ReadLine()
Catch ex As Exception
MsgBox(ex.Message)
End Try
Also, I have tried using the stream.length feature however, i got an exception saying something along the lines of "this stream does not support seek functions".
Thanks in advance

Taking Json from API and iterating over the results

So I feel stupid for asking probably a easy question but I'm not very familiar with .NET and I've been googling for a while now.
I'm looking to take in data from a web API and be able to iterate over it. The data looks like this
[
{"id":"5", "date":"01-01-2014"},
{"id":"90", "date":"05-01-2013"}
]
What I've got so far:
Private Sub newGetData()
Dim request As HttpWebRequest
Dim response As HttpWebResponse = Nothing
Dim reader As StreamReader
Try
request = DirectCast(WebRequest.Create("http://somesite.com"), HttpWebRequest)
response = DirectCast(request.GetResponse(), HttpWebResponse)
reader = New StreamReader(response.GetResponseStream())
Dim rawresp As String
rawresp = reader.ReadToEnd()
Dim jResults As JObject = JObject.Parse(rawresp)
Dim results As List(Of JToken) = jResults.Children().ToList
For Each item As JProperty In results
item.CreateReader()
MsgBox(item.name)
Next
'usernameTextbox.text = jResults("name").ToString()
'placenameTextbox.text = jResults("place")("name").ToString()
Catch ex As Exception
MsgBox(ex.ToString)
Finally
If Not response Is Nothing Then response.Close()
End Try
End Sub
I've tried a bunch of things but it always fails on the loop. How do I go about doing this?
EDIT: The error message for this one
Newtonsoft.Json.JsonReaderException: Error reading JObject from JsonReader. Current JsonReader item is not an object: StartArray. Path '', line 1, position 1.
at Newtonsoft.Json.Linq.JObject.Load(JsonReader reader)
at Newtonsoft.Json.Linq.JObject.Parse(String json)
at Forecasting.Form1.newGetData() in

Ftp Connection Failure in VB.NET

Using the code below, I continue to get a "Unable to connect to the remote server" error at Using response as... I'm not quite sure whats wrong or where to look for help. FTP in .NET seems to be seldom used.
Ok, second stupid question. EnableSsl != Sftp?
Dim FTPrequest As FtpWebRequest = DirectCast(FtpWebRequest.Create(New Uri("ftp://176.31.212.85/dev/shm/Minecraft/world/players/Drise.dat")), FtpWebRequest)
FTPrequest.EnableSsl = True
FTPrequest.Credentials = New System.Net.NetworkCredential("user", "pass")
FTPrequest.Method = Ftp.DownloadFile
FTPrequest.UseBinary = True
FTPrequest.KeepAlive = False
Dim ftpstream As IO.Stream = Nothing
Using response As System.Net.FtpWebResponse = CType(FTPrequest.GetResponse(), System.Net.FtpWebResponse)
Using responseStream As IO.Stream = response.GetResponseStream
'loop to read & write to stream
Dim buffer(2047) As Byte
Dim read As Integer = 0
Do
read = responseStream.Read(buffer, 0, buffer.Length)
ftpstream.Write(buffer, 0, read)
Loop Until read = 0 'see Note(1)
responseStream.Close()
End Using
response.Close()
End Using
I'd like to provide some clarification I found later in regards to this question that I never got to posting. SFTP is part of the SSH family, not, SSL. VB.Net (since the last time I used it) does not support SFTP connections. There are some external libraries that do, but all of the ones I found required money.

continuous http stream

My app currently sends GET httpwberequests and parses the content after reading the response stream for each request and the repeats this process over and over. I need to implement a continuous http stream which uses the same GET request but the connection stays open, from what I understand. how would I change my existing code to do this?
Dim responseReader As StreamReader = Nothing
Dim Reader As StreamReader = Nothing
Dim responseData As String = ""
Dim webresponse As HttpWebResponse = Nothing
Dim responseStream As Stream = Nothing
Dim returnContent As String = Nothing
Dim cdata As Integer = 0
webRequest = TryCast(System.Net.WebRequest.Create(url), HttpWebRequest)
Try
webresponse = DirectCast(webRequest.GetResponse(), HttpWebResponse)
responseStream = webresponse.GetResponseStream
If webresponse.ContentEncoding.ToLower().Contains("gzip") Then
responseStream = New GZipStream(responseStream, CompressionMode.Decompress)
ElseIf webresponse.ContentEncoding.ToLower().Contains("deflate") Then
responseStream = New DeflateStream(responseStream, CompressionMode.Decompress)
End If
Reader = New StreamReader(responseStream, Encoding.Default)
responseData = Reader.ReadToEnd()
Catch
Throw
Finally
webRequest.GetResponse().GetResponseStream().Close()
Reader.close()
End Try
Return responseData
The streaming HTTP implementation allows one to cosume data in real time over a single persistent HTTp request. It access a data feed that continues to send activities on that response. I need to read data from the response, process it and then continue reading from the response and continue this process until the connection is closed.
Would this be like a asynchronous request instead?
This is actually one of the goals of HTML5. You can take a look at http://socket.io/ to see implementations that work for HTML4 browsers