VB:NET "Object reference not set to an instance of an object." in a Net.WebResponse variable - vb.net

in the following code i am trying to handle different server resposes:
this function is used to read xml or html soruce from a web page
and in the commented line i get "Object reference not set to an instance of an object."
i wonder why.
Public Function GetPageHTML(ByVal URL As String, _
Optional ByVal TimeoutSeconds As Integer = 10) _
As String
' Retrieves the HTML from the specified URL,
' using a default timeout of 10 seconds
Dim objRequest As Net.WebRequest
Dim objResponse As Net.WebResponse
Dim objStreamReceive As System.IO.Stream
Dim objEncoding As System.Text.Encoding
Dim objStreamRead As System.IO.StreamReader
Try
' Setup our Web request
objRequest = Net.WebRequest.Create(URL)
objRequest.Timeout = TimeoutSeconds * 1000
' Retrieve data from request
Select Case CType(objResponse, Net.HttpWebResponse).StatusCode 'Here is where i get the error Object reference not set to an instance of an object.
Case Net.HttpStatusCode.InternalServerError
'This is sloppy, but a quick example for one of your sub-questions.
System.Threading.Thread.Sleep(10000)
'Try again.
objResponse = objRequest.GetResponse
Case Net.HttpStatusCode.BadRequest
'Error Handling
Case Net.HttpStatusCode.OK
'Proceed as normal.
Case Else
'Error Handling
End Select
objStreamReceive = objResponse.GetResponseStream
objEncoding = System.Text.Encoding.GetEncoding( _
"utf-8")
objStreamRead = New System.IO.StreamReader( _
objStreamReceive, objEncoding)
' Set function return value
GetPageHTML = objStreamRead.ReadToEnd()
' Check if available, then close response
If Not objResponse Is Nothing Then
objResponse.Close()
End If
Catch
' Error occured grabbing data, simply return nothing
Return ""
End Try
End Function
now when i remove the switch statement and just write the objResponse as
objResponse = objRequest.GetResponse
except i get an exception of error 403 or 503, i don't know how to handle this.

Your error line:
Select Case CType(objResponse, Net.HttpWebResponse).StatusCode
is called without ever assigning anything to objResponse.
You need to change it to:
objResponse = objRequest.GetResponse
Select Case CType(objResponse, Net.HttpWebResponse).StatusCode`
In regards to getting HTTP error codes for the page you are trying to ftech, here are the meanings of them and their causes:
http://en.wikipedia.org/wiki/List_of_HTTP_status_codes

First off, tcarvin is correct, your question's code is missing this line:
objResponse = objRequest.GetResponse
Secondly, you can do this to resolve your other issue:
If Not objResponse Is Nothing Then
'Select Case Code
Else
'Handle failure.
End If

Related

Error when downloading file through ADODB stream in VB code

We are getting an error message "Arguments are of the wrong type, are out of acceptable range, or are in conflict with one another" when opening an ADODB stream object for downloading a file automatically on the user's computer. The error is on the line objADOStream.Open and objADOStream.Write .GetReponseBody and we are using the following lines of code:
Private Sub oXMLHTTP_ResponseReady(ByVal ready As Boolean)
On Error GoTo oXMLHTTP_ResponseReady_EH
Call WriteLog("ready:" & ready & ", OutFilePathName:" & OutFilePathName, "oXMLHTTP_ResponseReady")
Dim objADOStream As Object
Dim fs As New FileSystemObject 'comment
If ready Then
With oXMLHTTP
If fs.FileExists(OutFilePathName) = True Then fs.DeleteFile (OutFilePathName)
Set objADOStream = CreateObject("ADODB.Stream")
'timer disable 'timerlastdat
TmrLastDataArrival.Enabled = False 'comment
objADOStream.Open
objADOStream.Type = 1 'adTypeBinary
objADOStream.Write .GetReponseBody
objADOStream.Position = 0 'Set the stream position to the start
objADOStream.SaveToFile OutFilePathName
objADOStream.Close
Set objADOStream = Nothing
End With
bDownloading = False
End If
Set fs = Nothing
Please assist in resolving.
Assuming that oXMLHTTP is an instance of IXMLHTTPRequest, then there is no method or property called GetResponseBody. However, there's a property responseBody.
And as far as I can tell, you simply store the web request's response to disk, for which I think using the ADODB.Stream object is overkill. Why not simply use VB's file handling commands (Open OutFilePathName As #...)? It takes 4 lines of code to do so:
Dim hFile As Long: hFile = FreeFile
Open OutFilePathName For Binary Access Write Shared As #hFile
Put #hFile, , oXMLHTTP.responseBody
Close #hFile

TCP Client-Side Not Recieveing Data Properly VB.NET

I'm trying to make a simple client-side application to recieve small text data, compare it and then does something on client machine depending on what server sent.
Server Logic: The server side is made in java, so can't change anything there. Server sends string "abc001" on connecting to client.
Client Logic: Client recieves the string "abc001" from server & checks if it's recieved string is the same as "abc001", then does something accordingly.
Problem: When the client recieves data, I display it in msgbox. But instead of just "abc001", there pops up an extra blank msgbox(image included).
Client Code - On Start:
Try
' declare vals
Dim ip As String = "127.0.0.1"
Dim port As Integer = 5000
' set client
_client = New TcpClient(ip, port)
' disable cross thread calls checking
CheckForIllegalCrossThreadCalls = False
' recieve msg
Threading.ThreadPool.QueueUserWorkItem(AddressOf RecieveMessages)
Catch ex As Exception
MsgBox(ex.ToString)
End Try
Client Code - Recieve Data
Private Sub RecieveMessages(state As Object)
Try
While True
Dim ns As NetworkStream = _client.GetStream()
Dim toRecieve(_client.ReceiveBufferSize) As Byte
ns.Read(toRecieve, 0, CInt(_client.ReceiveBufferSize))
Dim txt As String = Encoding.ASCII.GetString(toRecieve)
MsgBox(txt)
End While
Catch ex As Exception
MsgBox(ex.ToString)
End Try
End Sub
MsgBox 1
MsgBox 2
How to not get the blank msgbox. Even when compared, the data recived does not match parameters. Tried to use delay, tried fixing the buffer size to 6 bytes but no use.. Any help is appreciated. Thanks.
EDIT 1: Tried my best to figure it out but can't.. Tried cleaning the returned string data and even tried storing each return data in array. Saw the stack and it says the msgbox has "nothing" in it. It's null.. I don't even know what to do.. Here's the code for strings clean:
Private Sub RecieveMessages(state As Object)
Dim message(0) As String
Dim command_raw, command_clean, command As String
Dim counter As Integer = 0
Try
While True
Dim ns As NetworkStream = _client.GetStream()
Dim toRecieve(_client.ReceiveBufferSize) As Byte
ns.Read(toRecieve, 0, CInt(_client.ReceiveBufferSize))
Dim txt As String = Encoding.ASCII.GetString(toRecieve)
message(0) = txt
command_raw = message(0)
command_clean = command_raw.Replace(vbCrLf, Nothing)
command = command_clean.Substring(0, 6)
MsgBox(command)
End While
Catch ex As Exception
MsgBox(ex.ToString)
End Try
End Sub

VBA Excel: Retrieve/display email using Gmail API on excel

I research regarding retrieving or displaying emails from gmail without using outlook and it led me here on using Gmail API. I'm confused because I don't have idea on how to solve my problem.
Here's the code:
Attribute VB_Name = "Gmail"
' Setup client and authenticator (cached between requests)
Private pGmailClient As WebClient
Private Property Get GmailClient() As WebClient
If pGmailClient Is Nothing Then
' Create client with base url that is appended to all requests
Set pGmailClient = New WebClient
pGmailClient.BaseUrl = "https://www.googleapis.com/gmail/v1/"
' Use the pre-made GoogleAuthenticator found in authenticators/ folder
' - Automatically uses Google's OAuth approach including login screen
' - Get API client id and secret from https://console.developers.google.com/
' - https://github.com/timhall/Excel-REST/wiki/Google-APIs for more info
Dim Auth As New GoogleAuthenticator
Auth.Setup CStr(Credentials.Values("Google")("id")), CStr(Credentials.Values("Google")("secret"))
Auth.AddScope "https://www.googleapis.com/auth/gmail.readonly"
Auth.Login
Set pGmailClient.Authenticator = Auth
End If
Set GmailClient = pGmailClient
End Property
' Load messages for inbox
Function LoadInbox() As Collection
Set LoadInbox = New Collection
' Create inbox request with userId and querystring for inbox label
Dim Request As New WebRequest
Request.Resource = "users/{userId}/messages"
Request.AddUrlSegment "userId", "me"
Request.AddQuerystringParam "q", "label:inbox"
Dim Response As WebResponse
Set Response = GmailClient.Execute(Request)
If Response.StatusCode = WebStatusCode.Ok Then
Dim MessageInfo As Dictionary
Dim Message As Dictionary
For Each MessageInfo In Response.Data("messages")
' Load full messages for each id
Set Message = LoadMessage(MessageInfo("id"))
If Not Message Is Nothing Then
LoadInbox.Add Message
End If
Next MessageInfo
End If
End Function
' Load message details
Function LoadMessage(MessageId As String) As Dictionary
Dim Request As New WebRequest
Request.Resource = "users/{userId}/messages/{messageId}"
Request.AddUrlSegment "userId", "me"
Request.AddUrlSegment "messageId", MessageId
Dim Response As WebResponse
Set Response = GmailClient.Execute(Request)
If Response.StatusCode = WebStatusCode.Ok Then
Set LoadMessage = New Dictionary
' Pull out relevant parts of message (from, to, and subject from headers)
LoadMessage.Add "snippet", Response.Data("snippet")
Dim Header As Dictionary
For Each Header In Response.Data("payload")("headers")
Select Case Header("name")
Case "From"
LoadMessage.Add "from", Header("value")
Case "To"
LoadMessage.Add "to", Header("value")
Case "Subject"
LoadMessage.Add "subject", Header("value")
End Select
Next Header
End If
End Function
Sub Test()
Dim Message As Dictionary
For Each Message In LoadInbox
Debug.Print "From: " & Message("from") & ", Subject: " & Message("subject")
Debug.Print Message("snippet") & vbNewLine
Next Message
End Sub
I'm using the blank file from this GitHub Link that enables this code above. I was stuck on this error:
Still I don't have the idea what's the output of this API because it's my first time using this one. I have my id and secret already from Gmail API i just removed it from the code. I guess it was really hard if I don't have someone I can do brainstorming regarding on this matter.
Hoping someone have encountered this problem or anyone is interested. Thanks.

How do I upload data to a server with valid SSL certificate using a client vb.net program?

I am working on a program and uploads a shipping manifest to a the shippers website. When I try to upload, I get a nondescript error back from their server, and when checking with the shipper, they tell me that "there is an issue with the SSL" I am using.
I've spent quite a bit of time piecing together code that, from what I seem to understand, is supposed to work, but I'm not making any progress. As far as I know everything else is fine with the upload, but there is a problem with my SSL certificate
If I understand what this code is supposed to do correctly, I should get a certificate from the shippers website, which allows certification to my program for a space of time during which I can upload the data. I'm really not sure that this is what my code is doing at all, but the only code examples I have seen show it something like this.
Here's my code with the URLs changed:
'This references a custom class that compiles the manifest I'm going to upload
Dim StringToUpload As String = Compile_Manifest(MyDate, UseTestDB)
Dim webClient As New System.Net.WebClient
webClient.Credentials = System.Net.CredentialCache.DefaultCredentials
'From what I understand,
'this is supposed to set up properties used in next section of code
System.Net.ServicePointManager.SecurityProtocol = Net.SecurityProtocolType.Ssl3
System.Net.ServicePointManager.ServerCertificateValidationCallback = _
AddressOf AcceptAllCertifications
'I can see that this reaches the server,
'but I don't know how it relates to the next section of code
'that actually uploads the manifest
Dim ServerRequest As System.Net.WebRequest = _
System.Net.WebRequest.Create("https://www.certify.some-shippper.com:443/somefolder")
Dim ServerResponse As System.Net.WebResponse
ServerResponse = ServerRequest.GetResponse()
ServerResponse.Close()
'This code works for the upload of the manifest,
'and it seems the above code is unrelated and does not use a SSL certificate.
'When this code runs I get the same error back from the shippers server,
'indicating an issue with my SSL, with or without the two sections of code above.
Dim StrResult As String = ""
Dim WrappedString As String = TransmitPLD.WrapPldFile(StringToUpload)
'This references a custom class that wraps the data to upload
'in information from the shipper.
Dim ByesToUpload As Byte() = _
System.Web.HttpUtility.UrlEncodeToBytes(WrappedString, _
System.Text.ASCIIEncoding.ASCII)
Dim Result As Byte() = _
webClient.UploadData("https://www.certify.some-shippper.com:443/somefolder", _
ByesToUpload)
StrResult = System.Web.HttpUtility.UrlDecode(Result, _
System.Text.ASCIIEncoding.ASCII)
MessageBox.Show(StrResult)
So it turns out I went about it the wrong way. I needed to upload my data through System.Net.WebRequest and it takes care of the certificates for me. Not implementing all the parts of the code I needed, it didn't handle the retrieval of the shipper's certificate.
In case anyone else gets confused about the matter like I did, here's my working code for anyone to see, adapt and use. My resource for fixing the code (and by that I mean starting from scratch) was the MSDN page for the WebRequest class, and it has code examples much the same as what I have below in C++, C#, and VB.NET and here is the link.
First there are some global variables that need to be set and class that needs to be created for to store the upload response:
' This is set in the function that Upload function
' and uploads the data in the ReadCallback sub
Private Shared WrappedString As String
' This is used to wait for the callback in the Upload function
Private Shared allDone As New Threading.ManualResetEvent(False)
Friend Class RequestState
' This class stores the request state of the request.
Public request As Net.WebRequest
Public Sub New()
request = Nothing
End Sub ' New
End Class ' RequestState
Then there is a sub needed for the upload part web request which will be called further below in the upload function:
Private Shared Sub ReadCallback(asynchronousResult As IAsyncResult)
Try
Dim myRequestState As RequestState = CType(asynchronousResult.AsyncState, RequestState)
Dim myWebRequest As Net.WebRequest = myRequestState.request
' End the request.
Dim streamResponse As IO.Stream = myWebRequest.EndGetRequestStream(asynchronousResult)
' Convert the string into a byte array.
Dim byteArray As Byte() = System.Text.Encoding.ASCII.GetBytes(WrappedString)
' Write the data to the stream.
streamResponse.Write(byteArray, 0, byteArray.Length)
streamResponse.Close()
' Allow the main thread to resume.
allDone.Set()
Catch ex As Exception
Throw New Exception("Error in " & Reflection.MethodBase.GetCurrentMethod.Name.ToString & " **" & ex.Message, ex)
End Try
End Sub ' ReadCallback
Finally, this is the function that should be called to upload the data, which uses all the code above:
Public Shared Function Upload(ByVal MyDate As Date) As String
Dim StrResult As String = ""
UploadSucess = False
Try
' This is my code that builds the manifest that I want to upload
Dim StringToUpload As String = Compile_PLD200(MyDate)
WrappedString = TransmitPLD.WrapPldFile(StringToUpload)
Dim myWebRequest As Net.WebRequest
myWebRequest = Net.WebRequest.Create("https://www.some.website.com:443/someplace")
' Create an instance of the RequestState and assign
' myWebRequest to it's request field.
Dim myRequestState As New RequestState()
myRequestState.request = myWebRequest
myWebRequest.ContentType = "multipart/mixed; boundary=BOUNDARY"
myRequestState.request.Method = "POST"
' Start the asynchronous 'BeginGetRequestStream' method call.
Dim r As IAsyncResult = CType(myWebRequest.BeginGetRequestStream(AddressOf ReadCallback, myRequestState), IAsyncResult)
' Pause the current thread until the async operation completes.
allDone.WaitOne()
' Send the Post and get the response.
Dim myWebResponse As Net.WebResponse = myWebRequest.GetResponse()
Dim streamResponse As IO.Stream = myWebResponse.GetResponseStream()
Dim streamRead As New IO.StreamReader(streamResponse)
Dim readBuff(256) As [Char]
Dim count As Integer = streamRead.Read(readBuff, 0, 256)
While count > 0
Dim outputData As New [String](readBuff, 0, count)
Console.WriteLine(outputData)
count = streamRead.Read(readBuff, 0, 256)
StrResult += outputData
End While
' Close the Stream Object.
streamResponse.Close()
streamRead.Close()
' Release the HttpWebResponse Resource.
myWebResponse.Close()
Catch ex As Exception
Throw New Exception("Error in " & Reflection.MethodBase.GetCurrentMethod.Name.ToString & " **" & ex.Message, ex)
End Try
Return StrResult
End Function ' Upload
Again here is the MSDN page for the WebRequest class which has a code example too.
Hope this helps anyone who was stuck like I was. And any criticisms as to the implementation of the code are welcome. This just happen to do what I want, I can't say it is the most efficient implementation.

vb.net Handling the server response when trying to read xml from some page

I have the following function which i use to get html source from my website
Public Function GetPageHTML(ByVal URL As String, _
Optional ByVal TimeoutSeconds As Integer = 10) _
As String
' Retrieves the HTML from the specified URL,
' using a default timeout of 10 seconds
Dim objRequest As Net.WebRequest
Dim objResponse As Net.WebResponse
Dim objStreamReceive As System.IO.Stream
Dim objEncoding As System.Text.Encoding
Dim objStreamRead As System.IO.StreamReader
Try
' Setup our Web request
objRequest = Net.WebRequest.Create(URL)
objRequest.Timeout = TimeoutSeconds * 1000
' Retrieve data from request
Try
objResponse = objRequest.GetResponse 'some times it gives an error server unavailable 503
Catch ex As WebException
MsgBox(ex.Message)
End Try
objStreamReceive = objResponse.GetResponseStream
objEncoding = System.Text.Encoding.GetEncoding( _
"utf-8")
objStreamRead = New System.IO.StreamReader( _
objStreamReceive, objEncoding)
' Set function return value
GetPageHTML = objStreamRead.ReadToEnd()
' Check if available, then close response
If Not objResponse Is Nothing Then
objResponse.Close()
End If
Catch
' Error occured grabbing data, simply return nothing
Return ""
End Try
End Function
some times the objResponse gives error "503 Server unavailable" and many other errors like 403 and so on, how can i handle each of those errors independently?
how can i make this function retry the request after sometime? problem is the try statement doesn't seem to handle this and i am not sure why i don't see the exception MsgBox but it shows the error on the debugger.
Cast the response as a HttpWebResponse object and do a Select Case of it's StatusCode Property. You'll have to clean and finish this up, but here is an example:
Select Case CType(objResponse, Net.HttpWebResponse).StatusCode
Case Net.HttpStatusCode.InternalServerError
'This is sloppy, but a quick example for one of your sub-questions.
System.Threading.Thread.Sleep(10000)
'Try again.
objResponse = objRequest.GetResponse
Case Net.HttpStatusCode.BadRequest
'Error Handling
Case Net.HttpStatusCode.OK
'Proceed as normal.
Case Else
'Error Handling
End Select