Solved

Disregarding a "500 internal server error" in a webservice

Posted on 2010-09-09
16
726 Views
Last Modified: 2012-05-10
My application uses an external webservice. That webservice has two methods: checksubscription and activatesubscription. The checksubscription method gives no problems, but the activatesubscription is problematic. That is because a subscription can only activated once, and on a second effort, the webservice returns an error. That is fine, the error is returned as xml. However, the http-headers also return a "500 internal server error". That is according to the specs:

http://www.w3.org/TR/2000/NOTE-SOAP-20000508/#_Toc478383529

But I can not get past the "500 internal server error" to read the xml

My code is basically this:

-------------------------
Dim oRequest As HttpWebRequest = WebRequest.Create(sUrl)
' then create and add the xml for the request
Try
    Dim oResponse As HttpWebResponse = oRequest.GetResponse()
    ' code to process the response
Catch ex As Exception
    ' return the error message
End Try
---------------------------

The http-headers create an exception on "oRequest.GetResponse()". In the Catch, the oResponse is not defined. Is it possible to ignore an error? Like in good old VBScript "On Error Resume Next" (which I wanted to stop using).

0
Comment
Question by:sybe
  • 9
  • 7
16 Comments
 
LVL 30

Expert Comment

by:MlandaT
Comment Utility
By delcaring "oResponse" outside the Try block, it will be accessible in the Catch

Dim oRequest As HttpWebRequest
Dim oResponse As HttpWebResponse

' then create and add the xml for the request
Try
    oRequest = WebRequest.Create(sUrl)
    oResponse = oRequest.GetResponse()
    ' code to process the response
Catch ex As Exception
    ' return the error message
End Try
0
 
LVL 30

Expert Comment

by:MlandaT
Comment Utility
The issue with the "the http-headers also return a '500 internal server error'" is not standard behaviour. A successful call to a web service should not return an error... remember that by a 'successful call to a web service' in this case we dont mean that the activatesubscription method should succeed.. whether the subscription is activated or not.. the web service should return appropriate state information.. e.g. maybe return a boolean which is true if activation was ok.. otherwise false is not... that sort of thing. The HTTP 500 error suggests a totally different issue... could be programming errors or improper error handling in the web service, or otherwise some or other error on the web service host. But the HTTP500 error cannot be used to signify that the subscription could not be activated.

To ignore the error, you just do nothing in the catch block, and execution will continue ot the statements after the Try..Catch block.
0
 
LVL 28

Author Comment

by:sybe
Comment Utility
That creates "Object reference not set to an instance of an object."
0
 
LVL 30

Expert Comment

by:MlandaT
Comment Utility
On which line?
0
 
LVL 28

Author Comment

by:sybe
Comment Utility
"System.NullReferenceException: Object reference not set to an instance of an object."

-> Select Case oResponse.StatusCode

oResponse is not an object
Dim oResponse As HttpWebResponse
    Try
        oResponse = oRequest.GetResponse()
    Catch ex As Exception

    End Try
    ProcessResponse(oResponse)
    oResponse.Close()



Private Sub ProcessResponse(ByVal oResponse As HttpWebResponse)
    Select Case oResponse.StatusCode

    End Select

End Sub

Open in new window

0
 
LVL 30

Expert Comment

by:MlandaT
Comment Utility
Seems the problem is occuring before the WebRequest is created. You have unfortunately left out some code here... However, before accessing oResponse in ProcessResponse, you need ot check whether it is nothing or not.

Private Sub ProcessResponse(ByVal oResponse As HttpWebResponse)

    If oResponse isnot nothing then

        Select Case oResponse.StatusCode

        End Select

    End If

End Sub


I have included a script below that you may perhaps copy some ideas from:

        Dim oRequest As WebRequest
        Dim oResponse As HttpWebResponse

        ' then create and add the xml for the request
        Try

            oRequest = WebRequest.Create("http://www.google.com/")
            oResponse = oRequest.GetResponse()

            Select Case oResponse.StatusCode

                Case HttpStatusCode.OK

                    Dim sr As New StreamReader(oResponse.GetResponseStream)
                    MsgBox(sr.ReadToEnd())
                    sr.Close()

                Case Else

                    MsgBox("Request returned status: " & [Enum].GetName(GetType(HttpStatusCode), oResponse.StatusCode))

            End Select

        Catch ex As Exception

            ' return the error message
            MsgBox(ex.ToString)

        End Try
0
 
LVL 28

Author Comment

by:sybe
Comment Utility
Thank you.

The problem is that an error is generated on
oResponse = oRequest.GetResponse()    'message: The remote server returned an error: (500) Internal Server Error."

If that error is caught, oResponse gives "Object reference not set to an instance of an object.", so nothing can be done with it.

I want to read the xml-message returned, but the 500-error seems to prevent that.



0
 
LVL 30

Expert Comment

by:MlandaT
Comment Utility
Yes. The error HTTP 500 error indicates an error on the web service that you are calling. In the code snippet I gave you for example, try accessing http://www.google1.com/ (which does not exist)... you will find that an exception is thrown on that same line.

You need to talk to who ever administers the web service host and they should resolve the problem. That error, like I said earlier, is most likely due to something broken on that end... and not in your code.

You can handle that error by parsing the text in the exception... so on this line you try to maybe check if the error is a 500 error and handle it accrodingly...

' return the error message
'MsgBox(ex.ToString)
if ex.message.contains("(500) Internal Server Error") then msgbox("This was a HTTP500 error")
0
IT, Stop Being Called Into Every Meeting

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

 
LVL 30

Expert Comment

by:MlandaT
Comment Utility
0
 
LVL 28

Author Comment

by:sybe
Comment Utility
I agree that the problem in this case isn't on my part.

But anyway, I'd like to get the xml returned, and that does not seem possible with WebRequest.GetResponse().
Ironically I adapted some Classic ASP code, and that *is* able to get the xml:


Private Function GetXMLClassic() As String

    Dim oXMLHttpRequest

    Dim sReturn As String

    oXMLHttpRequest = CreateObject("Microsoft.XMLHTTP")

    If bHTTPLogin Then

        oXMLHttpRequest.Open("POST", sUrl, False, sHTTPUserName, sHTTPPassWord)

    Else

        oXMLHttpRequest.Open("POST", sUrl, False)

    End If

    oXMLHttpRequest.setRequestHeader("Content-Type", "text/xml; charset=utf-8")

    oXMLHttpRequest.Send("" & oClientXML.InnerXml)



    sReturn = oXMLHttpRequest.responseText

    oXMLHttpRequest = Nothing

    Return sReturn

End Function

Open in new window

0
 
LVL 30

Expert Comment

by:MlandaT
Comment Utility
It should be easy to get teh returned XML... see the example I gave you.... try it out.. it returns the HTML for the Google home page and displays it in a messagebox (of course you could write to a file or put in a variable etc etc).

The method to do what you want is to basically get the ResponseStream from the oResponse object. That gives you a stream containing the data from the resource in your web request. The XML which you want will be in that Response Stream. Here we are wrapping that stream with a StreamReader and then just calling the ReadToEnd method on the StreamReader which returns a nice strign for us.

Dim sr As New StreamReader(oResponse.GetResponseStream)
dim theXML as string = sr.ReadToEnd())
sr.Close()

if Not String.IsNullOrEmpty(theXML) then Process(theXML)
0
 
LVL 28

Author Comment

by:sybe
Comment Utility
> it returns the HTML for the Google home page

Well, yes, but http://www.google.com/ does not return a 500 Internal Server Error.
The problem is that the webservice both returns a 500 internal server error (in the header AND some xml. The internal server error in the header prevents WebRequest.GetResponse() from reading the xml. The XML is useful, because it contains some details about the error.
0
 
LVL 30

Accepted Solution

by:
MlandaT earned 500 total points
Comment Utility
Can you maybe post a sample of the text being returned? ... since you say the web service returns both the 500 Internal Server Error and some XML.

My understanding is that the 500 Internal Server Error implies that an error has occured in the web service application that prevents it from returning the correct XML. You should only expect to receive correct adn valid XML only when there is no 500 Internal Server Error. I'm not exactly sure if we are understanding each other on the meaning and implication of the 500 Internal Server Error.

With most HTTP errors, capturing the error in a Try..Catch should give you the necessary details (also try capturing a WebException)... however... if I now understand you correctly, you want to capture the text at a level before even the httpresponse since the webresponse object automatically parses the response text for you.
0
 
LVL 28

Author Comment

by:sybe
Comment Utility
As the w3c recommendation says (http://www.w3.org/TR/2000/NOTE-SOAP-20000508/#_Toc478383529)

"In case of a SOAP error while processing the request, the SOAP HTTP server MUST issue an HTTP 500 "Internal Server Error" response and include a SOAP message in the response containing a SOAP Fault element"

That means that with webservices, http-error 500 does not necessarily mean that there was an internal server error as in "unable to process the code", but it can also mean "unable to process the (soap) request". If the webservice is written correctly it will always be able to return some xml. I tried sending an invalid XML-request, and the webservice returned XML with a message that the XML-request was invalid XML.

The issue is very clear: I want to read the XML returned by the webservice, even if there is a HTTP-error 500.
I have posted some code which does the job, but that is basically Classic ASP, and I wonder if it can be done with "WebRequest.GetResponse()". With the Classic ASP solution, I currently do a second (identical) request to the webservice to get the response XML. That  is not exactly the right way to do it.

> since the webresponse object automatically parses the response text for you.

Does it? I was not aware of that. AFAIK, it returns a String, which needs code to parse it as XML. But anyway, the parsing of the response text is not the problem here, but getting access to the response text.
0
 
LVL 30

Expert Comment

by:MlandaT
Comment Utility
Perhaps try to use the Microsoft.XMLHTTP from VB.NET then
0
 
LVL 28

Author Closing Comment

by:sybe
Comment Utility
The solution is to catch the WebException.

CType(webexception.Response, HttpWebResponse)

holds the responsexml.

0

Featured Post

What Should I Do With This Threat Intelligence?

Are you wondering if you actually need threat intelligence? The answer is yes. We explain the basics for creating useful threat intelligence.

Join & Write a Comment

Sometimes in DotNetNuke module development you want to swap controls within the same module definition.  In doing this DNN (somewhat annoyingly) swaps the Skin and Container definitions to the default admin selections.  To get around this you need t…
IntroductionWhile developing web applications, a single page might contain many regions and each region might contain many number of controls with the capability to perform  postback. Many times you might need to perform some action on an ASP.NET po…
Sending a Secure fax is easy with eFax Corporate (http://www.enterprise.efax.com). First, Just open a new email message.  In the To field, type your recipient's fax number @efaxsend.com. You can even send a secure international fax — just include t…
In this seventh video of the Xpdf series, we discuss and demonstrate the PDFfonts utility, which lists all the fonts used in a PDF file. It does this via a command line interface, making it suitable for use in programs, scripts, batch files — any pl…

762 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

12 Experts available now in Live!

Get 1:1 Help Now