Error Handling with HTTPWebRequests, VB.NET - vb.net

I've looked around and couldn't find an answer so I thought i'd ask it here.
I have a program the calls an API with login info passed in the header and the server returns some info upon authentication. The problem is if the user creds are incorrect, the program crashes and throws an exception. The error is 401. How do it catch this, and tell the user?
My code is:
Dim request = TryCast(System.Net.WebRequest.Create("https://myurl.com"), System.Net.HttpWebRequest)
request.Method = "GET"
request.Headers.Add("authorization", "Bearer " + AccessToken)
request.ContentLength = 0
Dim responseContent As String
Using response = TryCast(request.GetResponse(), System.Net.HttpWebResponse)
Using reader = New System.IO.StreamReader(response.GetResponseStream())
responseContent = reader.ReadToEnd()
MessageBox.Show(responseContent)
End Using
End Using
Thanks.

Use a try catch statement
try
'My error prone code
catch ex as Exception
'Handle my error
end try
Try
Dim request = TryCast(System.Net.WebRequest.Create("https://myurl.com"), System.Net.HttpWebRequest)
request.Method = "GET"
request.Headers.Add("authorization", "Bearer " + AccessToken)
request.ContentLength = 0
Dim responseContent As String
Using response = TryCast(request.GetResponse(), System.Net.HttpWebResponse)
Using reader = New System.IO.StreamReader(response.GetResponseStream())
responseContent = reader.ReadToEnd()
MessageBox.Show(responseContent)
End Using
End Using
Catch ex As Exception
MessageBox.Show(ex.ToString(), "Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
End Try

Related

PUT API call is deleting record instead of updating

I am trying to update data in API using PUT request, but instead its deleting that particular row.
I see some forum to include saving option but where am i supposed to do it. if i do requesturl/save then i get error of "method not value"
my code
Try
Dim myRequest As HttpWebRequest = DirectCast(WebRequest.Create(requestURL), HttpWebRequest)
With myRequest
.Method = "PUT"
.ContentType = "application/json"
.Headers.Add("Authorization", "Bearer " & authHeaderString)
End With
Using streamWriter = New StreamWriter(myRequest.GetRequestStream())
streamWriter.Write(jsonobj)
' streamWriter.Close()
End Using
Return myRequest
Catch ex As Exception
sMessage = ex.Message
Return Nothing
End Try

Connect to WebRequest Server

I'm trying to connect to TNT's server for making XML request.
First I'm trying to just make a successful connection (before trying to send anything).
According to TNT everything is set up ok. So I'm thinking it's on my end.
I'm using the code below. But it just comes back with, that it's unauthorized.
Dim request As WebRequest = WebRequest.Create("https://express.tnt.com/expressconnect/track.do?version=3")
Dim authInfo As String = ("username" + (":" + "password"))
authInfo = Convert.ToBase64String(Encoding.Default.GetBytes(authInfo))
request.Headers("Authorization") = ("Basic " + authInfo)
request.AuthenticationLevel = System.Net.Security.AuthenticationLevel.MutualAuthRequested
request.ContentType = "application/x-www-form-urlencoded"
request.Method = "POST"
Try
Dim response As WebResponse = request.GetResponse
Console.Write(response)
Catch ex As Exception
Console.WriteLine(ex.Message)
End Try
Console.ReadLine()
Can anyone help or shed any light on what i am doing wrong?

DotNet app receives Gateway 502 (proxy server error) - after posting large file to web server

I've seen questions like this asked in a few places but I haven't seen an answer which helps me. Hoping that you can assist!
Situation:
Uploading files using a .NET workstation client to an Apache web server backed by Tomcat.
Small files work just fine. Larger files POSTS are rejected with http error 401 around the .copyto command. The subsequent GetResponse errors out with the message "The remote server returned an error: (502) Bad Gateway. The proxy server received an invalid response from an upstream server" The error is seen immediately. It's not timing out.
CURL can upload the same "large" file without issue.
The terms "small" and "large" are relative: small = 88 bytes. large = 3.17 MB. I understand that this "large" file is tiny for most purposes.
So, the problem must be in my code. Here is a simplified form of that code (leaving out the exception handlers).
Dim request As HttpWebRequest = CType(WebRequest.Create("http://mysite"), HttpWebRequest)
request.Method = "POST"
request.Credentials = New NetworkCredential("userid","password")
request.ContentType = "application/octet-stream"
request.SendChunked = True
request.UserAgent = "Support Tools"
request.CookieContainer = New CookieContainer
Using fileStream As Stream = New FileStream("C:\sourceFile", FileMode.Open)
request.ContentLength = fileStream.Length
Dim uploadStream As Stream = request.GetRequestStream
fileStream.CopyTo(uploadStream)
End Using
Dim response As WebResponse = request.GetResponse()
Thank you for your time.
Per request, here is the complete code. Note that it relies upon variables defined elsewhere within the class.
Public Sub SubmitFileToSis(ByVal operation As String, ByVal sourceFile As String)
Dim request As HttpWebRequest = WebRequest.Create(_EndPoints(operation.ToLower))
request.Method = "POST"
request.Credentials = New NetworkCredential(_SisUserId, _SisUserPassword)
request.ContentType = "application/octet-stream"
request.SendChunked = True
request.UserAgent = "Support Tools"
request.CookieContainer = New CookieContainer
Try
Using fileStream As Stream = New FileStream(sourceFile, FileMode.Open)
request.ContentLength = fileStream.Length
Dim uploadStream As Stream = request.GetRequestStream
fileStream.CopyTo(uploadStream)
End Using
Catch ex As WebException
If (ex.Status = WebExceptionStatus.ProtocolError) Then
Dim response As WebResponse = ex.Response
Using sr As StreamReader = New StreamReader(response.GetResponseStream())
_SubmissionResult = String.Format("Error Uploading: {0} - {1} - {2}", ex.Status.ToString, ex.Message, sr.ReadToEnd())
End Using
Else
_SubmissionResult = String.Format("Error Uploading: {0} - {1} ", ex.Status.ToString, ex.Message)
End If
Exit Sub
Catch ex As Exception
_SubmissionResult = String.Format("Error Uploading: {0} ", ex.Message)
Exit Sub
End Try
Try
Dim response As WebResponse = request.GetResponse()
Using sr As New StreamReader(response.GetResponseStream(), Encoding.UTF8)
_SubmissionResult = sr.ReadToEnd()
End Using
_SubmittedDataSetUid = GetBetween(_SubmissionResult, "reference code ", " to track")
Catch ex As WebException When (ex.Status = WebExceptionStatus.ProtocolError)
If (ex.Status = WebExceptionStatus.ProtocolError) Then
Dim response As WebResponse = ex.Response
Using sr As StreamReader = New StreamReader(response.GetResponseStream())
_SubmissionResult = String.Format("Error Reading Response: {0} - {1} - {2}", ex.Status.ToString, ex.Message, sr.ReadToEnd())
End Using
Else
_SubmissionResult = String.Format("Error Reading Response: {0} - {1} ", ex.Status.ToString, ex.Message)
End If
Exit Sub
Catch ex As Exception
_SubmissionResult = String.Format("Error Reading Response: {0} ", ex.Message)
Exit Sub
End Try
End Sub
Eureka!! I needed to add "Authorization" to the HttpWebRequest Headers. There were a couple of other minor changes but they were for readability and cleanliness.
The new working template (at least for crawling stage) is:
Dim request As HttpWebRequest = WebRequest.Create("http://mysite")
request.Method = WebRequestMethods.Http.Post
request.Credentials = New NetworkCredential("userid","password")
request.ContentType = "application/octet-stream"
request.SendChunked = True
request.UserAgent = "Support Tools"
request.CookieContainer = New CookieContainer
Dim authInfo As String = Convert.ToBase64String(Encoding.UTF8.GetBytes(String.Format("{0}:{1}", "userid","password")))
request.Headers.Add("Authorization", String.Format("Basic {0}", authInfo))
Using fileStream As Stream = New FileStream("C:\sourceFile", FileMode.Open, FileAccess.Read)
request.ContentLength = fileStream.Length
Dim uploadStream As Stream = request.GetRequestStream
fileStream.CopyTo(uploadStream)
End Using
Dim response As WebResponse = request.GetResponse()

Betfair NG API Navigation Application Menu error

I am trying to create a Betfair app written in VB.NET using Betfair NG API.
I am trying to request the navigation menu in VB.NET utilizing the following instructions, here, but I get error 400 Bad request. Could someone send me a code for doing so?
Sub GetNavigatorManu(ByVal SessToken As String, ByVal AppKey As String)
Dim request As HttpWebRequest = Nothing
Dim response As HttpWebResponse = Nothing
Dim strResponseStatus As String = ""
Try
request = WebRequest.Create(New Uri("https://api.betfair.com/exchange/betting/rest/v1/en/navigation/menu.json"))
request.Accept = "application/json"
request.Method = "GET"
request.KeepAlive = True
request.ContentType = "application/json"
request.AutomaticDecompression = DecompressionMethods.GZip Or DecompressionMethods.Deflate
request.Headers.Add("Accept-Encoding", "gzip,deflate")
request.Headers.Add("X-Authentication", SessToken)
request.Headers.Add("X-Application", AppKey)
response = request.GetResponse()
Display the status below
strResponseStatus = "Status is " & CType(response, HttpWebResponse).StatusCode
Catch ex As Exception
MsgBox("CreateRequest Error" & vbCrLf & ex.Message)
End Try
MsgBox(strResponseStatus)
End Sub

How can I read the response from a web request when the Status is not 200?

I am having difficulty getting the response text from a HTTP web request in vb.net when I get a web exception.
This is the code I am doing it with.
Try
myWebResponse = CType(request.GetResponse(), HttpWebResponse)
myStreamReader = New StreamReader(myWebResponse.GetResponseStream())
ResponseText = myStreamReader.ReadToEnd
If myWebResponse.StatusCode = HttpStatusCode.Accepted Or myWebResponse.StatusCode = 200 Then
SendResult = True 'Sent
SendStatus = 1 'message sent successfully
Try
Integer.TryParse(myWebResponse.Headers("Number-Of-MT-PDU"), num_MT_PDU)
Catch ex As Exception
End Try
Else
SendStatus = 2 'message processed but not sent successfully
End If
Catch e As WebException
If (e.Status = WebExceptionStatus.ProtocolError) Then
Dim response As WebResponse = e.Response
Using (response)
Dim httpResponse As HttpWebResponse = CType(response, HttpWebResponse)
statusCode = httpResponse.StatusCode
Try
myStreamReader = New StreamReader(response.GetResponseStream())
Using (myStreamReader)
ResponseText = myStreamReader.ReadToEnd & "Status Description = " & HttpWebResponse.StatusDescription
End Using
Catch ex As Exception
Logger.LogError(Me, ex)
End Try
End Using
Annoyingly, the API I am contacting uses a 404 as a valid response. If I put the request in a browser some message text will be displayed. I want to be able to use that text in my program. I can not simply use the error code to determine actions as I don't think I can differentiate between a valid 404 response and an actual error.
In the code this line
myWebResponse = CType(request.GetResponse(), HttpWebResponse)
throws an exception.
In the exception I can get the 404 code and the description but not the response stream. It is always null.
If I get a 200 response I get the text in the Response stream no problem.
In the web exception response object (in Visual Studios debugger) I have checked the headers and the object values and can't find the response text anywhere. If I stick the request URL in a browser I get response text back even though it is a 404.
The raw response in fiddler:
HTTP/1.1 404 Not Found Connection: close Content-Type: text/plain; charset=UTF-8 Content-Length: 35 "The response Message"
Any ideas on how I can get "The response Message" in my program? I have to use .Net on the server.
Thanks for any help anybody can give.
This LINQPad query works fine, dumping the HTML provided by my web server's "Not Found" error web page:
Dim rq = System.Net.WebRequest.Create(New Uri("http://localhost/test"))
Try
Dim rs = rq.GetResponse
rs.Dump
Catch Ex As System.Net.WebException
Dim rs = Ex.Response
Call (New StreamReader(rs.GetResponseStream)).ReadToEnd.Dump
End Try
FYI Your code works for me, except the presumed typo re HttpWebResponse.StatusDescription (and commenting out "unrelated stuff"), again as a LINQPad query (in .NET 4.0):
Dim request = WebRequest.Create("http://localhost/test")
Dim myStreamReader As StreamReader
Dim SendStatus As Integer = -1
Dim statusCode As HttpStatusCode
Dim ResponseText As String
Try
Dim myWebResponse = CType(request.GetResponse(), HttpWebResponse)
myStreamReader = New StreamReader(myWebResponse.GetResponseStream())
ResponseText = myStreamReader.ReadToEnd
If myWebResponse.StatusCode = HttpStatusCode.Accepted Or myWebResponse.StatusCode = 200 Then
'SendResult = True 'Sent
SendStatus = 1 'message sent successfully
'Try
' Integer.TryParse(myWebResponse.Headers("Number-Of-MT-PDU"), num_MT_PDU)
'Catch ex As Exception
'End Try
Else
SendStatus = 2 'message processed but not sent successfully
End If
Catch e As WebException
If (e.Status = WebExceptionStatus.ProtocolError) Then
Dim response As WebResponse = e.Response
Using (response)
Dim httpResponse As HttpWebResponse = CType(response, HttpWebResponse)
statusCode = httpResponse.StatusCode
Try
myStreamReader = New StreamReader(response.GetResponseStream())
Using (myStreamReader)
ResponseText = myStreamReader.ReadToEnd & "Status Description = " & httpResponse.StatusDescription ' HttpWebResponse.StatusDescription
End Using
Catch ex As Exception
'Logger.LogError(Me, ex)
ex.Dump("Exception")
End Try
End Using
End If
End Try
ResponseText.Dump("ResponseText")
I have also confirmed the above code (with the inferred As clauses added and converting the .Dump calls to Console.WriteLine) works in .NET 2.0 with VB8.
Note that the key is that even though the act of GetResponseStream() throws a .NET WebException, the HttpWebResponse is actually passed to the WebException object, so when in the Catch, you do a new GetResponseStream() on the WebException.Response object.
Below, very similar code for when in the Catch of the initial GetResponseStream()
Try
OriginalResponseStream = GetResponseStream(OriginalHTTPWebResponse)
Catch wex as WebException
Dim response As WebResponse = wex.Response
Dim statusCode As HttpStatusCode
Dim ResponseText As String
Dim httpResponse As HttpWebResponse = CType(response, HttpWebResponse)
statusCode = httpResponse.StatusCode
Try
Dim myStreamReader As New StreamReader(response.GetResponseStream())
Using (myStreamReader)
ResponseText = myStreamReader.ReadToEnd
Process(ResponseText) '<===as in whatever you need to do with the response
End Using
Catch ex As Exception
HandleIt(ex.Message) '<===as in whatever you want to do if Exception during the above
End Try
End Try