Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Handling Errors from HttpWebRequest.GetResponse

I'm having a ridiculous time trying to get an SMS API working (ZeepMobile, if you're interested) with .NET... I've been around .NET for a few years, but with all this social networking and API stuff, I need to get into the HttpWebRequest a bit. I'm new at it, but not completely new; I was able to hook up my site to Twitter without too much fuss (ie, I was able to modify someone's code to work for me).

Anyways, the way their API works is to send an SMS message, you send them a POST and they respond back to you. I can send it just fine, but every time I do, rather than echo back something helpful to figure out what the error is, I get the Yellow Error Page Of Death (YEPOD) saying something to the effect of "The remote server returned an error: (400) Bad Request." This occurs on my line:

'...creation of httpwebrequest here...'
Dim myWebResponse As WebResponse
myWebResponse = request.GetResponse() '<--- error line

Is there any way to simply receive the error from the server rather than have the webserver throw an exception and give me the YEPOD?

Or better yet, can anyone post a working example of their Zeep code? :)

Thanks!

EDIT: Here's my whole code block:

Public Shared Function SendTextMessage(ByVal username As String, _
ByVal txt As String) As String
    Dim content As String = "user_id=" + _
username + "&body=" + Current.Server.UrlEncode(txt)

    Dim httpDate As String = DateTime.Now.ToString("r")
    Dim canonicalString As String = API_KEY & httpDate & content

    Dim encoding As New System.Text.UTF8Encoding
    Dim hmacSha As New HMACSHA1(encoding.GetBytes(SECRET_ACCESS_KEY))

    Dim hash() As Byte = hmacSha.ComputeHash(encoding.GetBytes(canonicalString))
    Dim b64 As String = Convert.ToBase64String(hash)

    'connect with zeep'
    Dim request As HttpWebRequest = CType(WebRequest.Create(_
"https://api.zeepmobile.com/messaging/2008-07-14/send_message"), HttpWebRequest)
    request.Method = "POST"
    request.ServicePoint.Expect100Continue = False

    ' set the authorization levels'
    request.Headers.Add("Authorization", "Zeep " & API_KEY & ":" & b64)
    request.ContentType = "application/x-www-form-urlencoded"
    request.ContentLength = content.Length

    ' set up and write to stream'
    Dim reqStream As New StreamWriter(request.GetRequestStream())
    reqStream.Write(content)
    reqStream.Close()
    Dim msg As String = ""
    msg = reqStream.ToString

    Dim myWebResponse As WebResponse
    Dim myResponseStream As Stream
    Dim myStreamReader As StreamReader

    myWebResponse = request.GetResponse()

    myResponseStream = myWebResponse.GetResponseStream()
    myStreamReader = New StreamReader(myResponseStream)
    msg = myStreamReader.ReadToEnd()
    myStreamReader.Close()
    myResponseStream.Close()

    ' Close the WebResponse'
    myWebResponse.Close()
    Return msg
End Function
like image 516
Jason Avatar asked Jul 16 '09 20:07

Jason


People also ask

How do I dispose of HttpWebRequest?

HttpWebRequest does not implement IDisposable so it does not require disposing. just set the httprequest object to null once your done with it.

How do I read Httpwebresponse response?

If you call the GetRequestStream method, you must use the GetResponse method to retrieve the response. If a WebException is thrown, use the Response and Status properties of the exception to determine the response from the server.

What is HttpWebRequest C#?

The HttpWebRequest class provides support for the properties and methods defined in WebRequest and for additional properties and methods that enable the user to interact directly with servers using HTTP.

What is Web exception?

The WebException class is thrown by classes descended from WebRequest and WebResponse that implement pluggable protocols for accessing the Internet. When WebException is thrown by a descendant of the WebRequest class, the Response property provides the Internet response to the application.


2 Answers

Try this:

Dim req As HttpWebRequest = DirectCast(WebRequest.Create(url), HttpWebRequest)
'' set up request
Try
    Using response = req.GetResponse()
        '' success in here
    End Using
Catch ex As WebException
    Console.WriteLine(ex.Status)
    If ex.Response IsNot Nothing Then
        '' can use ex.Response.Status, .StatusDescription
        If ex.Response.ContentLength <> 0 Then
            Using stream = ex.Response.GetResponseStream()
                Using reader = New StreamReader(stream)
                    Console.WriteLine(reader.ReadToEnd())
                End Using
            End Using
        End If
    End If
End Try

C# version

HttpWebRequest req = (HttpWebRequest) WebRequest.Create(url);
// set up request
try {
    using (var response = req.GetResponse()) {
        // success in here
        }
}
catch (WebException ex) {
    Console.WriteLine(ex.Status);
    if (ex.Response != null) {
        // can use ex.Response.Status, .StatusDescription
        if (ex.Response.ContentLength != 0) {
            using (var stream = ex.Response.GetResponseStream()) {
                using (var reader = new StreamReader(stream)) {
                    Console.WriteLine(reader.ReadToEnd());
                }
            }
        }
    }    
}

Here's your code, modified a bit:

Try
    'connect with zeep'
    Dim request As HttpWebRequest = CType(WebRequest.Create( _
"https://api.zeepmobile.com/messaging/2008-07-14/send_message"), HttpWebRequest)
    request.Method = "POST"
    request.ServicePoint.Expect100Continue = False

    ' set the authorization levels'
    request.Headers.Add("Authorization", "Zeep " & API_KEY & ":" & b64)
    request.ContentType = "application/x-www-form-urlencoded"
    request.ContentLength = content.Length

    ' set up and write to stream'
    Using requestStream As Stream = request.GetRequestStream()
        Using requestWriter As New StreamWriter(requestStream)
            requestWriter.Write(content)
        End Using
    End Using

    Using myWebResponse As WebResponse = request.GetResponse()
        Using myResponseStream As Stream = myWebResponse.GetResponseStream()
            Using myStreamReader As StreamReader = New StreamReader(myResponseStream)
                Return myStreamReader.ReadToEnd()
            End Using
        End Using
    End Using
Catch ex As WebException
    Console.WriteLine(ex.Status)
    If ex.Response IsNot Nothing Then
        '' can use ex.Response.Status, .StatusDescription
        If ex.Response.ContentLength <> 0 Then
            Using stream = ex.Response.GetResponseStream()
                Using reader = New StreamReader(stream)
                    Console.WriteLine(reader.ReadToEnd())
                End Using
            End Using
        End If
    End If
End Try

Dumping headers:

Dim headers As WebHeaderCollection = request.Headers
' Displays the headers. Works with HttpWebResponse.Headers as well
Debug.WriteLine(headers.ToString())

' And so does this
For Each hdr As String In headers
    Dim headerMessage As String = String.Format("{0}: {1}", hdr, headers(hdr))
    Debug.WriteLine(headerMessage)
Next
like image 77
John Saunders Avatar answered Oct 19 '22 07:10

John Saunders


I think it's normal for a WebException to be thrown when the request returns a 4xx or 5xx code. You just need to catch it and handle it appropriately.

Have you looked at the Headers collection after the call to GetResponse?

it just throws an exception at the GetResponse... how would I check the headers after that?

Try
    myWebResponse = request.GetResponse()
Catch x As WebException
    log, cleanup, etc.
Finally
    log/inspect headers?
End Try
like image 25
Tim Sylvester Avatar answered Oct 19 '22 07:10

Tim Sylvester