tags:

views:

875

answers:

3

Hello

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

A: 

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.

Justin Niessner
A: 

Thanks allot for your reply Justin but im still having problems.

I tried to modify the phpcode:

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

and when I try:

UserProfile user = service.getUserProfile();

Will get conversion error: Error 1 Cannot implicitly convert type 'SoapApp.SimpleService.UserProfile' to 'SoapApp.Form1.UserProfile' C:\Users\opx\Documents\Visual Studio 2008\Projects\SoapApp\SoapApp\Form1.cs 38 33 SoapApp

Am still trying to get rid of UserProfileArray, else I will have to start splitting the string result. Thanks again, - opx

A: 

I had the same problem, and it was because I was trying to create an object locally with the same name as the object being returned from the WebService.

What I needed to do instead, was to allow the Service Reference to manage this process, and define the object for me, based on what it read from the WSDL.

So, with a service reference called "localWS", then the following applies:

localWS.ServReference ws = new localWS.ServReference(); localWS.ServReference.MyObject obj = localWS.ServReference.MyObject(); obj = localWS.ServReference.CallMethodHere();

wyerarch