Introduction
OK, I have struggled with this for hours; Google searches didn't help a lot - apart from questions of similar problems that have been left unanswered in a number of forums. Sometimes, when you call an AXIS-based web service from a .NET client, you receive a null
(Nothing
in VB) response. Since I don't consider at all the possibility of being the first one facing this issue, I figured that this solution will provide at least a good basis for someone dealing with it.
Background
The problem: A partner of mine deployed an AXIS-based web service on his machine. Since I had already started my ASP.NET 2.0 project, I tried to invoke his modules from VB.NET. While Visual Studio managed to read the WSDL successfully and build the proxy class, I kept receiving NULL
responses (Nothing
) from his web services. However, there was nothing wrong with his implementation since other types of web clients worked smoothly (I even tried this beautiful generic SOAP client). The strange thing was that I received no exception from .NET, the service seemed to run normally. And it actually did.
So, to sum it up: the code below (which is normally how you'd expect a .NET client to invoke a WS) returned null
(Nothing
in VB):
Dim WS As New AxisService.Service1
Dim strFullNameXML as String
strFullNameXML=WS.doMergeNames("John","Doe")
Well, strFullName
is always Nothing
. No error thrown, just an empty value. The exact same behaviour both for ASP .NET 1.1 and 2.0.
Using the code
The solution: After placing breakpoints and overloading some methods to trace the response, I found out that the service indeed returned the correct string, just .NET had a hard time to read it (weird characters maybe?).
Thus, the problem was solved by creating a new class that inherits from Service1
and overriding the GetWebResponse
function to capture the full, correct SOAP response to a variable of mine and then parse the SOAP envelope manually.
Here is the code:
Imports System.Xml
Imports System.Net
Namespace AxisService
Public Class myService1
Inherits AxisService.Service1
Private m_Return As String
Public Property _ResultStr() As String
Get
Return m_Return
End Get
Set(ByVal value As String)
?>
'<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
' <soapenv:Body>
' <dlwmin:doMergeNamesResponse xmlns:dlwmin="http://test.test.com/">
' <return>return string</return>
' </dlwmin:ddoMergeNamesResponse>
' </soapenv:Body>
'</soapenv:Envelope>
Dim tmpXML As New XmlDocument
tmpXML.LoadXml(value)
Dim tmpValueNodeList As XmlNodeList
Dim tmpValueNode As XmlNode
tmpValueNodeList = _
tmpXML.DocumentElement.GetElementsByTagName("soapenv:Body")
If tmpValueNodeList.Count > 0 Then
tmpValueNode = tmpValueNodeList.Item(0)
End If
If Not tmpValueNode Is Nothing Then
Me.m_Return = tmpValueNode.InnerText
Else
Me.m_Return = ""
End If
End Set
End Property
Protected Overloads Overrides Function GetWebResponse(ByVal _
the_webRequest As WebRequest) As WebResponse
Dim WR As WebResponse
WR = MyBase.GetWebResponse(the_webRequest)
Dim sr As New IO.StreamReader(WR.GetResponseStream)
Me._ResultStr = sr.ReadToEnd
Return MyBase.GetWebResponse(the_webRequest)
End Function
End Class
End Namespace
The above code stores the correct result string to the _ResultSt
r property. However, since you are reading the response stream before returning it to the rest of the execution, an exception is going to be thrown. This is expected; therefore, in order to call this web service, you will have to refer to the new class, trap the exception, and get the _ResultStr
property as follows:
Dim WS As New AxisService.myService1
Dim strFullNameXML as String
Try
WS.doMergeNames("John","Doe")
Catch ex As Exception
End Try
Dim strReturn As String = WS._ResultStr
Points of interest
I know, it is a terrible hack, but it is quick and dirty :)... plus, I had no time finding out something more elegant. Perhaps, a more neat solution would be to override a couple of other SOAP/.NET internal functions in order to correct the response parsing instead of overlapping it.
History
- 26 October 2007: First code submission.