C# struct and NuSOAP(php)

cnusoapPHP

Im trying to build a client in c# that talks with some remote (php)server with SOAP using the NuSOAP library.
Here im using a struct/object that will containt the user info of some user:

public struct UserProfile {
            public string username;
            public string password;
            public string email;
            public string site;
            public string signature;
            public int age;
            public int points;

And this is the PHP Code:

server->wsdl->addComplexType(
                'UserProfile',
                'complexType',
                'struct',
                'all',
                '',
                array(
                    'username' => array('name' => 'username', 'type' => 'xsd:string'),
                    'password' => array('name' => 'password', 'type' => 'xsd:string'),
                    'email' => array('name' => 'email', 'type' => 'xsd:string'),
                    'site' => array('name' => 'site', 'type' => 'xsd:string'),
                    'signature' => array('name' => 'signature', 'type' => 'xsd:string'),
                    'age' => array('name' => 'age', 'type' => 'xsd:int'),
                    'points' => array('name' => 'username', 'type' => 'xsd:int'),
                )
);

$server->wsdl->addComplexType(
                'UserProfileArray',
                'complexType',
                'array',
                '',
                'SOAP-ENC:Array',
                array(),
                array(array('ref' => 'SOAP-ENC:arrayType', 'wsdl:arrayType' => 'tns:UserProfile[]')),
                'tns:UserProfile'
);

$server->register("getUserProfile",
    array(),
    array('return' => 'tns:UserProfileArray'),
    $namespace,
    false,
    'rpc',
    false,
    'Get the user profile object'
);

function getUserProfile(){
    $profile['username'] = "user";
    $profile['password'] = "pass";
    $profile['email'] = "usern@ame";
    $profile['site'] = "u.com";
    $profile['signature'] = "usucsdckme";
    $profile['age'] = 111;
    $profile['points'] = time() / 2444;

    return $profile;
}

Now I already have a working login function, and I want to get the info about the logged in user but I dont know howto obtain these. This is what im using to get the userinfo:

            string user = txtUser.Text;
            string pass = txtPass.Text;
            SimpleService.SimpleService service = new SimpleService.SimpleService();
            if(service.login(user, pass)){
                 //logged in

            }

            SoapApp.SimpleService.UserProfile[] user = service.getUserProfile(); // THIS LINE GIVES ME AN EXCEPTION

            MessageBox.Show(user[0].username + "--" + user[0].points);

The getUserProfile() function produces an error:

System.Web.Services.Protocols.SoapException was unhandled
  Message="unable to serialize result"
  Source="System.Web.Services"

or I get something like 'cant parse xml' error.

The article I used for this was from: http://www.sanity-free.org/125/php_webservices_and_csharp_dotnet_soap_clients.html
The difference on what they are doing and what I try to do is that I only want to get one object returned instead of multiple 'MySoapObjects'.

I hope someone is familiar with this and could help me, thanks in advance!
Regards,
opx

Best Answer

At first glance, it looks like the problem is that you set up your WSDL in PHP so that your getUserProfile() method returns an array of UserProfile objects. By looking at the method, it actually only returns a single UserProfile object...and C# is expecting it to be an array of objects.

In short, your WSDL and code are out of sync. I think you need to change the code where you register the method with the WSDL:

$server->register("getUserProfile",
    array(),
    array('return' => 'tns:UserProfile'),
    $namespace,
    false,
    'rpc',
    false,
    'Get the user profile object'
);

You'll also have to change the C# code calling the web service to something like this:

UserProfile user = service.getUserProfile();

And then you can get rid of the whole WSDL registration for the UserProfileArray type.