Friday, December 12, 2008

Calling a PHP SOAP 1.2 web service using Visual Studio and VB.Net

Oh the fun of learning new technologies.  The endless errors, outbursts of profanity, stumping dead-ends…and finally, the trill of success!  Nothing beats it in my book.  This story is about my latest “trophy” (a fishing metaphor), creating a PHP web service and then calling it from a .NET console application.  Once you get everything working, it all seems so simple…but rest assured, creating a WSDL file by hand can be a tricky experience if you are new to one of the technologies in question.  First things first, to follow this example you need to download the sample application that contains a couple of PHP files and console application.  I tried to boil this down to the Hello World level so it would be easiest to understand.  I assume you already have PHP setup and have enabled the SOAP extension. Here is the part that took me awhile to get working.  I wanted a web service that took a string as a parameter and returned a string.  Apparently Visual Studio requires this “complexType” description in the “types” section; otherwise you could just define your parameters in the “message” section and be done with it.

      <s:element name="GetReportsListRequest">

        <s:complexType>

          <s:sequence>

            <s:element minOccurs="1" maxOccurs="1" name="Category" type="s:string"/>

          </s:sequence>

        </s:complexType>

      </s:element>

      <s:element name="GetReportsListResponse">

        <s:complexType>

          <s:sequence>

            <s:element minOccurs="1" maxOccurs="1" name="ReportsList" type="s:string"/>

          </s:sequence>

        </s:complexType>

      </s:element>

When VS2005 reads this WSDL (lots of XML omitted in the above – see download), it generates the following stub:

Public Function GetReportsList(ByVal Category As String) As String

Now another tricky part was getting the PHP service to return the string in the correct object hierarchy.  It took the following code to do so:

function GetReportsList($P) {

  $reportList = "Report1|Report2" . $P->Category;

  return array("ReportsList"=>$reportList);

}

For an example of how to return complex types, see the references section at the end of this article.

One other quirky thing was how to call the web service from a PHP client (I’ll throw that in for free).  You have to wrap your parameter array in a blank array because of the WSDL GetReportsListRequest hierarchy:

$return = $client->__soapCall("GetReportsList",array(array( "Category" => "abc")));

References:

PHP SOAP Manual
User Comment in SoapServer.addFunction documentation
Trouble with Visual Studio and WSDL
WSDL Essentials

 

No comments: