Web request not repeating after failure, try/catch not working - vb.net

I am trying to send a web request to a Snom PA1 bell. The bell rings periodically throughout the day, but occasionally times out trying to contact the bell. That would be fine, but after this happens a couple times, the web request stops sending altogether. the sub still runs, but no bells. Also, while debugging, the webrequest throws a webexception that is not handled by the catch, even though it is contained within the try/catch.
Does anyone know why the web request would stop working after a failure?
Private Sub ringIPBell(ByVal params() As Object, Optional ByVal secondattempt As Boolean = False)
Dim IPaddress As String = params(0)
Dim ringSeconds As Double = params(1)
Dim wr As Net.HttpWebRequest
If ringSeconds = 2 Then
wr = Net.HttpWebRequest.Create("http://" & IPaddress & "/line_login.htm?l=2")
Else
wr = Net.HttpWebRequest.Create("http://" & IPaddress & "/line_login.htm?l=1")
End If
wr.Method = "post"
wr.CachePolicy = New System.Net.Cache.RequestCachePolicy(System.Net.Cache.RequestCacheLevel.NoCacheNoStore) 'added Oct2010
wr.Credentials = New Net.NetworkCredential("correctName", "correctPassword")
Dim postdata As String = "PLAY_RINGER:1=Play Ringer"
wr.ContentLength = postdata.Length + 2
Dim requestStream As IO.Stream, strmwrit As IO.StreamWriter
Try
requestStream = wr.GetRequestStream()
strmwrit = New IO.StreamWriter(requestStream)
strmwrit.WriteLine(postdata)
strmwrit.Close()
Dim responsestream As New IO.StreamReader(wr.GetResponse.GetResponseStream)
Catch ex As System.Net.WebException
If Not secondattempt Then
ringIPBell(params, True)
End If
Dim testvar As String = ex.ToString
Catch ex As Exception
Beep()
End Try
Also, I previously had the following code ringing the bell, but it would only work for one of the two bells, Even though as far as i can tell their settings were identical.
requestStream = wr.GetRequestStream()
strmwrit = New IO.StreamWriter(requestStream)
strmwrit.WriteLine(postdata)
strmwrit.Close()
requestStream.Close()
As suggested I broke out the responestream line as such:
requestStream = wr.GetRequestStream()
strmwrit = New IO.StreamWriter(requestStream)
strmwrit.WriteLine(postdata)
strmwrit.Close()
it breaks on "requestStream = wr.GetRequestStream()"
with the error:
"A first chance exception of type 'System.Net.WebException' occurred in System.dll
Additional information: The operation has timed out"

Related

VB.NET ~ PUT WebRequest raising exceptions when trying to GetResponse of it

I am getting TWO exceptions. The first one in the regular code and the second into the exception handling block.
I have this function (below) that supposed to change user settings in a Web API using PUT method. Everything runs fine until the point that I try to get a response from the web request. Then it raises the first exception (unknown) and when I try to handle the error I get a second exception "Object reference not set to an instance of an object".
As far as I know normally what will cause this error is the attempt of getting a response of an unassigned web request, but in this case it IS assigned and the Uri is valid. All the credentials for authorization are correct too.
This is my code:
Try
Dim webRequest As System.Net.HttpWebRequest
webRequest = System.Net.HttpWebRequest.Create(InternalSettings.APIurl + "/config")
webRequest.Headers("Authorization") = InternalSettings.APIpwd
webRequest.Headers("API-Application-Key") = InternalSettings.APIkey
webRequest.Method = "PUT"
webRequest.ContentType = "application/x-www-form-urlencoded"
Dim postData As String = ""
postData += "SaveAllCustomersData=false"
Dim byteArray As Byte() = Encoding.UTF8.GetBytes(postData)
Dim dataStream As Stream = webRequest.GetRequestStream()
dataStream.Write(byteArray, 0, byteArray.Length)
dataStream.Close()
'The next line will raise an unknown exception
Dim myHttpWebResponse As HttpWebResponse = webRequest.GetResponse
Dim responseReader As StreamReader = New StreamReader(myHttpWebResponse.GetResponseStream())
Dim responseData As String = responseReader.ReadToEnd()
responseReader.Close()
webRequest.GetResponse().Close()
Catch ex As WebException
'The next line will raise a "Object reference not set to an instance of an object" exception
Dim resp = New StreamReader(ex.Response.GetResponseStream()).ReadToEnd()
Dim obj = JsonConvert.DeserializeObject(resp)
Return False
End Try
If you are using basic authentification you can try something like this:
Dim strUrl As String = InternalSettings.APIurl + "/config"
Dim request As WebRequest = DirectCast(WebRequest.Create(strUrl), HttpWebRequest)
Dim strResponse As String = ""
Dim byteAuth() As Byte = Encoding.UTF8.GetBytes(InternalSettings.APIkey & ":" & InternalSettings.APIpwd)
Dim strPost As String = "SaveAllCustomersData=false"
Dim bytePost() As Byte = Encoding.UTF8.GetBytes(strPost)
request.ContentType = "application/x-www-form-urlencoded"
request.Method = "PUT"
request.Headers.Add("Authorization", "Basic " & Convert.ToBase64String(byteAuth))
Using sw = New StreamWriter(request.GetRequestStream())
sw.Write(bytePost, 0, bytePost.Length)
sw.Flush()
Using response As HttpWebResponse = request.GetResponse()
Using sr = New StreamReader(response.GetResponseStream())
strResponse = sr.ReadToEnd()
End Using
End Using
End Using

Having trouple uploading to virtual directory via http in vb.net

Trying to upload an image to HTTP virtual directory and I keep getting this exception:
A first chance exception of type 'System.Net.WebException' occurred in System.dll
at System.Net.HttpWebRequest.GetResponse()
Dim mFileStream As New FileStream("/Image Location/", FileMode.Open)
Dim mRequest As WebRequest = WebRequest.Create("/URL/")
mRequest.Headers.Set("filename", "new name")
mRequest.Proxy = New WebProxy("/URL/", True)
mRequest.Method = "POST"
mRequest.ContentLength = mFileStream.Length
Dim mCredentials As New NetworkCredential
mCredentials.Password = "/pass/"
mCredentials.UserName = "/Login Name/"
mRequest.Credentials = mCredentials
Dim mData(mFileStream.Length - 1) As Byte
mFileStream.Read(mData, 0, mFileStream.Length)
mFileStream.Close()
Using dataStream As Stream = mRequest.GetRequestStream()
dataStream.Write(mData, 0, mData.Length)
dataStream.Close()
End Using
Dim mResponse As HttpWebResponse = CType(mRequest.GetResponse(), HttpWebResponse)
mResponse.Close()
Upon further investigation, I have found the reason for the WebException is:
ProtocolError The remote server returned an error: (405) Method Not Allowed.
The answer was quite simple despite everything i tried
you have to specify the file name in the url
Dim mRequest As WebRequest = WebRequest.Create("/URL/")
to
Dim mRequest As WebRequest = WebRequest.Create("/URL/" & FileName & FileExtention)
ex:
Dim mRequest As WebRequest = WebRequest.Create("http://1.1.1.1/niveimage.png")

Error handling in a callback in vb.net

New to asynchronous calls, in this case using a call back. The code below works.
The code is calling a rather rudimentary web service which returns xml. If the service returns xml the code works fine and msresponse is filled with the xml and the funcion "GetWebserviceData" is able to return, to the caller, a parsed msresponse through the function "CreateDT_Implantable_Device". This works without a hitch as long as xml is returned.
If the service does not return any xml there is an error thrown at this line in the respcallback:
" Dim resp As HttpWebResponse = _
CType(req.EndGetResponse(ar), HttpWebResponse)"
The error that is thrown is "400-bad request)"
It seems that if the service fails the thread for the callback does not complete correctly and the entire application locks up at that point. It returns to the vb.net form that called "GetWebserviceData" and none of the controls work: the form is frozen.
I have tried putting try catches around all the code in call back function (as seen below), "respcallback" and around all the code in "GetWebserviceData" (not in the code below). as you can see from the try catch in "respcallback" in case of this error I am trying to end the callback thread and fill msResponse so the loop in "GetWebserviceData" that follows is satisfied and will end. Here is the loop.
Do While msResponse.Length = 0
'wait
Loop
The complete code follows: Any help would be appreciated. I am trying allow the webservice to fail, let the code continue and put up a messagebox saying the service failed. Obviously my try catch is not working as seen in "respcallback"; the code simply locks up.
Code follows. Any help would be appreciated:
Public Function GetWebserviceData(psUDI As String) As DataTable
FillGS1Delimeters()
miUDI = psUDI
' Create the request object.
'Try
Dim wreq As HttpWebRequest = _
CType(WebRequest.Create("https://accessgudid.nlm.nih.gov/api/v1/devices/lookup.xml?udi=" & psUDI), HttpWebRequest)
' Create the state object.
Dim rs As RequestState = New RequestState()
' Put the request into the state so it can be passed around...
rs.Request = wreq
' Issue the async request..
Dim r As IAsyncResult = _
CType(wreq.BeginGetResponse( _
New AsyncCallback(AddressOf RespCallback), rs), IAsyncResult)
' Wait until the ManualResetEvent is set so that the application
' does not exit until after the callback is called.
allDone.WaitOne()
Do While msResponse.Length = 0
'wait
Loop
'Catch ex As Exception
'msResponse = "Error"
'MessageBox.Show("an error")
'End Try
Return CreateDT_Implantable_Device(msResponse)
End Function
Private Function CreateDT_Implantable_Device(wsResponse As String)
Dim dtDevice As DataTable = New DataTable()
Dim dtPI As DataTable = New DataTable()
Dim ds As DataSet = New DataSet
createEmptyDeviceTable(dtDevice)
createEmptyPITable(dtPI)
ds = StoreXMLAsText(msResponse)
dtPI = FillRecord(dtDevice, ds)
Return dtPI
End Function
Shared Sub RespCallback(ar As IAsyncResult)
Try
' Get the RequestState object from the async result.
Dim rs As RequestState = CType(ar.AsyncState, RequestState)
' Get the HttpWebRequest from RequestState..
Dim req As HttpWebRequest = rs.Request
' Call EndGetResponse, which returns the HttpWebResponse object
' that came from the request issued above.
Dim resp As HttpWebResponse = _
CType(req.EndGetResponse(ar), HttpWebResponse)
' Start reading data from the respons stream.
Dim ResponseStream As Stream = resp.GetResponseStream()
' Store the reponse stream in RequestState to read
' the stream asynchronously.
rs.ResponseStream = ResponseStream
' Pass rs.BufferRead to BeginRead. Read data into rs.BufferRead.
Dim iarRead As IAsyncResult = _
ResponseStream.BeginRead(rs.BufferRead, 0, BUFFER_SIZE, _
New AsyncCallback(AddressOf ReadCallBack), rs)
Catch ex As Exception
msResponse = "Invalid UDI"
MessageBox.Show(ex.Message)
msResponse = "Error"
End Try
End Sub
Shared Sub ReadCallBack(asyncResult As IAsyncResult)
' Get the RequestState object from the AsyncResult.
Dim rs As RequestState = CType(asyncResult.AsyncState, RequestState)
' Retrieve the ResponseStream that was set in RespCallback.
Dim responseStream As Stream = rs.ResponseStream
' Read rs.BufferRead to verify that it contains data.
Dim read As Integer = responseStream.EndRead(asyncResult)
If read > 0 Then
' Prepare a Char array buffer for converting to Unicode.
Dim charBuffer(1024) As Char
' Convert byte stream to Char array and then String.
' len contains the number of characters converted to Unicode.
Dim len As Integer = _
rs.StreamDecode.GetChars(rs.BufferRead, 0, read, charBuffer, 0)
Dim str As String = New String(charBuffer, 0, len)
' Append the recently read data to the RequestData stringbuilder
' object contained in RequestState.
rs.RequestData.Append( _
Encoding.ASCII.GetString(rs.BufferRead, 0, read))
' Continue reading data until responseStream.EndRead
' returns –1.
Dim ar As IAsyncResult = _
responseStream.BeginRead(rs.BufferRead, 0, BUFFER_SIZE, _
New AsyncCallback(AddressOf ReadCallBack), rs)
Else
If rs.RequestData.Length > 1 Then
' Display data to the console.
Dim strContent As String
strContent = rs.RequestData.ToString()
msResponse = strContent
Console.WriteLine(strContent)
End If
' Close down the response stream.
responseStream.Close()
' Set the ManualResetEvent so the main thread can exit.
allDone.Set()
End If
Return
End Sub
Here is what you want to reference from MSDN.
https://msdn.microsoft.com/en-us/library/2e08f6yc(v=vs.110).aspx?cs-save-lang=1&cs-lang=vb#code-snippet-1
Seems it would be much easier using Async and Await tho...

Background Program Not Looping

I have a program that runs in the background looping to check if a page on the site has been changed. It works once and shows the message box but if I change it again it won't do anything.
Imports System.Net
Imports System.String
Imports System.IO
Module Main
Sub Main()
While 1 = 1
Dim client As WebClient = New WebClient()
Dim reply As String = client.DownloadString("http://noahcristinotesting.dx.am/file.txt")
If reply.Contains("MsgBox") Then
Dim Array() As String = reply.Split(":")
MessageBox.Show(Array(2), Array(1))
Dim request As System.Net.FtpWebRequest = DirectCast(System.Net.WebRequest.Create("ftp://noahcristinotesting.dx.am/noahcristinotesting.dx.am/file.txt"), System.Net.FtpWebRequest)
request.Credentials = New System.Net.NetworkCredential("username", "password")
request.Method = System.Net.WebRequestMethods.Ftp.UploadFile
Dim path As String = "C:\test.txt"
Dim createText As String = "completed"
File.WriteAllText(path, createText)
Dim fileftp() As Byte = System.IO.File.ReadAllBytes("C:\test.txt")
Dim strz As System.IO.Stream = request.GetRequestStream()
strz.Write(fileftp, 0, fileftp.Length)
strz.Close()
strz.Dispose()
End If
End While
End Sub
End Module
Not sure at this moment what is causing it to crash when run outside of the IDE, but try trapping exceptions that are being thrown in the loop. I imagine there's an exception happening, cratering your app. The below catch block is by no means production ready, normally you want to catch specific exceptions in order to handle them effectively, but this is a cheap way to see if an exception is being thrown and what it is at runtime.
Sub Main()
Try
While 1 = 1
Dim client As WebClient = New WebClient()
Dim reply As String = client.DownloadString("http://noahcristinotesting.dx.am/file.txt")
If reply.Contains("MsgBox") Then
Dim Array() As String = reply.Split(":")
MessageBox.Show(Array(2), Array(1))
Dim request As System.Net.FtpWebRequest = DirectCast(System.Net.WebRequest.Create("ftp://noahcristinotesting.dx.am/noahcristinotesting.dx.am/file.txt"), System.Net.FtpWebRequest)
request.Credentials = New System.Net.NetworkCredential("username", "password")
request.Method = System.Net.WebRequestMethods.Ftp.UploadFile
Dim path As String = "C:\test.txt"
Dim createText As String = "completed"
File.WriteAllText(path, createText)
Dim fileftp() As Byte = System.IO.File.ReadAllBytes("C:\test.txt")
Dim strz As System.IO.Stream = request.GetRequestStream()
strz.Write(fileftp, 0, fileftp.Length)
strz.Close()
strz.Dispose()
End If
End While
Catch ex As Exception
MsgBox(ex.ToString)
End Try
End Sub
Alternatively, you could check your event viewer in windows to see if a .net application exception is being logged. Event Viewer > Windows Logs > Application

How to get result from failing webclient.downloadstring?

If we use webclient.downloadstring on a server with error, we got nothing
Try
result = webClient.DownloadString("https://api.bodis.com/domainclassification?domain=" + CurrentBlog.Domain)
Catch ex As Exception
System.Windows.Forms.Application.DoEvents()
End Try
Usually result contains the response. But in case of error result is empty.
I want to know something. For example, even if the result is bad, usually there is a custom 404 message, etc.
The api.bodis.com is problematic because it mix secure and non secure stuff. However, it gives output anyway in internet explorer. I want to use webclient and I want to know the ouput
Getting ex.response yields nothing
Dim adult = webClient.DownloadString("http://googleads.g.doubleclick.net/apps/domainpark/domainpark.cgi?callback=_google_json_callback&output=js&client=ca-dp-godaddy2_xml&domain_name=" + CurrentBlog.Domain)
'ias.NavigateTillComplete("https://api.bodis.com/domainclassification?domain=" + CurrentBlog.Domain)
Dim result = ""
Dim url = "http://api.bodis.com/domainclassification?domain=" + CurrentBlog.Domain
Dim webRequest = DirectCast(System.Net.HttpWebRequest.Create(url), System.Net.HttpWebRequest)
Dim response As HttpWebResponse
Try
response = DirectCast(webRequest.GetResponse(), HttpWebResponse)
Catch ex As System.Net.WebException
System.Windows.Forms.Application.DoEvents()
response = DirectCast(ex.Response, HttpWebResponse) 'is nothing there
End Try
Dim responseStream = response.GetResponseStream