Access Asp.Net WebService from PHP Client

Creating and consuming webservices in asp.net is an easy task with the help of Visual Studio. Although most of the scenarios I worked with were always with asp.net applications consuming asp.net web services, which makes things even easier. This week however I learned something new when I had to get a PHP client application to connect to my asp.net webservices.

One of out clients was called saying that the service was not working. When I tested hisPHP client I noticed the the parameters that he was passing where not getting to my webservice even though the service was being called. The only problem then was passing the parameters. I Googled a little and got my own PHP client running.

For the sake of this post let’s say that our webservice gets an string as a parameters and returns the same value, this will let us test our code. So here is the asp.net webservice:

[WebService(Namespace = "http://tempuri.org/")]
public class Service : System.Web.Services.WebService
{

    [WebMethod]
    public string MyTestMethod(string myParameter)
    {
        return "The value of the parameter is: " + myParameter;
    }

}

As you can see there’s nothing to it.

The PHP code is not much harder once you Google a little. First you have to haveNuSoap Library which has the webservices infrastructure for PHP. You may put it in the same directory of your test page. Then you code a simple client to access our service:

<?php

    require_once('./nusoap.inc');

    $wsdl = "http://mysite/myapp/Service.asmx?wsdl";

    $mynamespace = "http://tempuri.org/";

    $theVariable = array('myParameter'=> 'gabriel');

    $s = new SoapClient($wsdl,true);

    $result = $s->call('MyTestMethod',$theVariable);

    echo "<h1>Resultado:</h1>";

    echo "<pre>"; print_r($result); print "</pre>";
?>

After I had the code I could verify for my self that my client was right. The parameters in the above code are not getting to the webservice. The coding is right, I checked in several sites in the Internet, so where could the problem be?

Well, SOAP specification allows for two formatting options: Style and Use. Style handles the formatting of the Body element of the envelope. Style allows for 2 values:
  1. RPC (Remote Procedure Call) which is the older format;
  2. Document which is a newer format and is VisualStudio default format.

By now I bet you have figured out the solution, right? If you said that PHP default encoding is RPC and asp.net default encoding is Document then you’re right on.

How to solve the problem? Well, you can solve the problem on both ends, it all depends on your choice. First let’s fix it on the asp.net side, it’s really simple. All you have to do is use the SoapRpcMethod attribute on WebMethod, like this:

[WebService(Namespace = "http://tempuri.org/")]
public class Service : System.Web.Services.WebService
{

    [SoapRpcMethod()]
    [WebMethod]
    public string MyTestMethod(string myParameter)
    {
        return "The value of the parameter is: " + myParameter;
    }

}

That’s it, the PHP client starts to work instantly.

This is a good solution if you only had PHP clients, since that was not my case I didn’t want to mess with my webservice and have to make changes to all other asp.net clients. I wanted to solve the problem on the PHP client, so let’s see how we could code the PHP client to fix the problem.

<?php

    require_once('./nusoap.inc');

    $wsdl = "http://mysite/myapp/Service.asmx?wsdl";

    $mynamespace = "http://tempuri.org/";

    $theVariable = array('myParameter'=> 'gabriel');

    $s = new SoapClient($wsdl,true);

    //here is the only change you need to do
    $result = $s->call('MyTestMethod',array('parameters' =>  $theVariable));

    echo "<h1>Resultado:</h1>";

    echo "<pre>"; print_r($result); print "</pre>";
?>

What I had to do in the PHP code was to add an extra array around the array with the original variables. This handles the difference in the Document encoding used by asp.net.

This problem really got on my nerves last week and I’m really glad to have found a solution. As usual I wanted to share this with the world and maybe avoid the same headache to others. Ohh, and I also got to learn a little php on the way…

Happy coding friends!