Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / web / ASP.NET

Invoking a Java/AXIS Web Service from .NET

4.00/5 (6 votes)
26 Oct 2007CPOL2 min read 1  
Invoking a Java/AXIS Web Service from a .NET-based client. Using the automatic web reference addition provided by VS.NET may cause an empty (null) response.

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):

VB
'***Let's pretend that you have added a web reference
'   to a Java-enabled web service called Service1

'***The name of this web reference is AxisService

'***This service contains a web method called doMergeNames,
'   receiving two arguments, FName and SName, returning an XML string

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:

VB
'I recommend you place this in a public module
' so that it is accessible from any part of your project

Imports System.Xml
Imports System.Net

Namespace AxisService
    '********that is a TERRIBLE HACK for accessing Java-Web services**************

    'for some STUPID reason all I got was null return values

    'I had to override the GetWebResponse and parse the SOAP return myself

    '*****************************************************************************

    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)
                'parse the soap string

                'something like the following

                '<?xml version="1.0" encoding="utf-8" ?> 

                '<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 _ResultStr 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:

VB
Dim WS As New AxisService.myService1
Dim strFullNameXML as String

'trap the exception due to the stupid hack ***********

Try
  WS.doMergeNames("John","Doe")
Catch ex As Exception
 'do something here if you want to

'maybe check for the specific exception number, 
'I can't remember it :)

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.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)