.NET Framework Developer Center >
.NET Development Forums
>
.NET Framework Networking and Communication
>
Help with Net.WebRequest/WebResponse
Help with Net.WebRequest/WebResponse
- We have some legacy code which makes use of the MS XML Core Services ("Msxml2.XMLHTTP.3.0") and needed to be upgraded/updated. The whole purpose of the legacy code was to post some data to a remote server over HTTPS and get the response it returned. They way I have always done this in .Net is to use the Net.WebRequest and Net.WebResponse objects, however it seems what I came up with is not returning the same pieces of info required that the old way was.For example, the old way would create the object by referencing the MSXML.XMLHTTP.3.0 DLL. Then it would execute the Open() method passing in the type as "POST", the URL of the remote server, and the username and password if applicable. It would then execute SetRequestHeader() setting the content type as "text/xml", invoke the Send() method, and then get the properties: ResponseText, Status, and StatusText. And finally, it would finish by invoking Close().Using the example at http://msdn.microsoft.com/en-us/library/debx8sh9.aspx as a starting point I implemented the following in a Web Service (.asmx) so it could be used by our non-.Net applications via SOAP requests:''' <summary>''' Gets a response from a remote server which requires credentials''' </summary>''' <param name="ReqURL">URL of remote server to query for response</param>''' <param name="ReqTimeout">Timeout in milliseconds for the response</param>''' <param name="ReqType">Content Type for the request</param>''' <param name="PostData">Data or content to post in the request</param>''' <param name="UserName">User Name for the secure request</param>''' <param name="Password">Password for the secure request</param>''' <returns>Delimited String: StatusCode ~ StatusDescr ~ ResponseText</returns>''' <remarks></remarks><WebMethod()> _Public Function GetResponsePWP(ByVal ReqURL As String, ByVal ReqTimeout As Integer, ByVal ReqType As String, ByVal PostData As String, ByVal UserName As String, ByVal Password As String) As StringDim Creds As New NetworkCredential() With {.UserName = UserName, .Password = Password}Dim DataStream As StreamDim HTTPResponse As HttpWebResponseDim nmsResponseText As String = ""Dim nmsStatusDescr As String = ""Dim nmsStatusCode As String = ""Dim Request As WebRequestDim Response As WebResponseDim byteArray As Byte() = Encoding.UTF8.GetBytes(PostData)TryRequest = WebRequest.Create(ReqURL)Request.Method = "POST"Request.ContentType = ReqType '"text/xml" or "text/plain"Request.ContentLength = byteArray.LengthRequest.Timeout = ReqTimeoutRequest.Credentials = CredsDataStream = Request.GetRequestStreamDataStream.Write(byteArray, 0, byteArray.Length)DataStream.Flush()DataStream.Close()Response = Request.GetResponseHTTPResponse = CType(Response, HttpWebResponse)nmsStatusDescr = HTTPResponse.StatusDescriptionnmsStatusCode = CStr(HTTPResponse.StatusCode)DataStream = Response.GetResponseStreamUsing Reader As New StreamReader(DataStream)nmsResponseText = Reader.ReadToEndReader.Close()End UsingDataStream.Close()Response.Close()Return String.Format("{0}~{1}~{2}", nmsStatusCode, nmsStatusDescr, nmsResponseText)Catch ex As ExceptionReturn String.Format("{0}~{1}~GetResponsePWP() Failed: {2}{3}", nmsStatusCode, nmsStatusDescr, vbCrLf, ex.Message)End TryEnd FunctionThe code works great as long as there are no errors, or invalid passwords, or it doesn't time out, etc. For example..... I removed one of the required elements in the XML and posted it to the webservice and there seems to be a problem. It’s not returning the any content like the old way used to.With the old XMLHTTP method we get this:status=409statusText=ConflictresponseText=<?xml version="1.0"?><exchange_response><error><code>24</code><name>INVALID_PATIENT_IDENTIFIER</name><description>invalid/missing patient_sid element</description></error></exchange_response>Posting the same XML to the new service I get this:~~GetResponsePWP() Failed: The remote server returned an error: (409) Conflict.Another example with a malformed XML string using old method:status=400statusText=Malformed XMLresponseText=<html><head><title>400 Malformed XML</title></head><body><h1>400 Malformed XML</h1><p /><hr /><small>Resin-3.1.s070406 (built Fri, 06 Apr 2007 04:13:31 GMT)</small></body></html>Result from new service:~~GetResponsePWP() Failed: The remote server returned an error: (400) Bad Request.In short, when the Web Service encounters an error, it throws an exception but I don't get the the pieces back I was expecting. Can someone help me understand what I am doing wrong here or how to get at the pieces in the same manner as was returned like the old way?Thanks!-- Andrew
Answers
- Took quite a bit of Googling but I eventually found the answer to this one.....In the code I posted, the exception (when a bad password, malformed XML, etc.) occurred on the line "Response = Request.GetResponse". Because it pops up at this point, I didn't get the HTTPWebResponse object's properties to return. As it turns out though, if the exception is a "WebExceptionStatus.ProtocolError" the exception variable will contain a pointer to an HTTPWebResponse object that can be used to get at the values I needed!So, I put a Try...Catch block around the "Response = Request.GetResponse" line and all is much better:TryResponse = Request.GetResponseCatch ex As WebExceptionSelect Case ex.StatusCase WebExceptionStatus.ProtocolErrorDim ErrResponse As HttpWebResponse = CType(ex.Response, HttpWebResponse)Dim ErrResult As String = New StreamReader(ErrResponse.GetResponseStream).ReadToEnd.ToStringIf ErrResult.Length = 0 Then ErrResult = ex.MessageReturn String.Format("{0}~{1}~{2}", CInt(ErrResponse.StatusCode).ToString, ErrResponse.StatusDescription.ToString, ErrResult)Case ElseReturn String.Format("{0}~{1}~{2}", nmsStatusCode, nmsStatusDescr, ex.Message)End SelectEnd TryI hope this helps someone.-- Andrew
- Marked As Answer byAndrewR73 Thursday, November 05, 2009 9:41 PM
All Replies
- Took quite a bit of Googling but I eventually found the answer to this one.....In the code I posted, the exception (when a bad password, malformed XML, etc.) occurred on the line "Response = Request.GetResponse". Because it pops up at this point, I didn't get the HTTPWebResponse object's properties to return. As it turns out though, if the exception is a "WebExceptionStatus.ProtocolError" the exception variable will contain a pointer to an HTTPWebResponse object that can be used to get at the values I needed!So, I put a Try...Catch block around the "Response = Request.GetResponse" line and all is much better:TryResponse = Request.GetResponseCatch ex As WebExceptionSelect Case ex.StatusCase WebExceptionStatus.ProtocolErrorDim ErrResponse As HttpWebResponse = CType(ex.Response, HttpWebResponse)Dim ErrResult As String = New StreamReader(ErrResponse.GetResponseStream).ReadToEnd.ToStringIf ErrResult.Length = 0 Then ErrResult = ex.MessageReturn String.Format("{0}~{1}~{2}", CInt(ErrResponse.StatusCode).ToString, ErrResponse.StatusDescription.ToString, ErrResult)Case ElseReturn String.Format("{0}~{1}~{2}", nmsStatusCode, nmsStatusDescr, ex.Message)End SelectEnd TryI hope this helps someone.-- Andrew
- Marked As Answer byAndrewR73 Thursday, November 05, 2009 9:41 PM


