2009-07-16 10 views
1

Je tente de construire un client dans C# qui parle avec un serveur distant (php) avec SOAP en utilisant la bibliothèque NuSOAP. Ici im en utilisant un struct/objet qui contiennent les informations de l'utilisateur de certains utilisateurs:C# struct et NuSOAP (php)

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

Et ceci est le code PHP:

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'] = "[email protected]"; 
    $profile['site'] = "u.com"; 
    $profile['signature'] = "usucsdckme"; 
    $profile['age'] = 111; 
    $profile['points'] = time()/2444; 

    return $profile; 
}

Maintenant, je l'ai déjà une fonction de connexion de travail, et je veulent obtenir l'information sur l'utilisateur connecté mais je ne sais pas comment les obtenir. C'est ce que im en utilisant pour obtenir le 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);

La fonction getUserProfile() produit une erreur:

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

ou je reçois quelque chose comme erreur 'Parse cant xml'.

L'article utilisé pour ce que je provenait: http://www.sanity-free.org/125/php_webservices_and_csharp_dotnet_soap_clients.html La différence sur ce qu'ils font et ce que j'essaie de faire est que je veux seulement obtenir un objet retourné au lieu de plusieurs « MySoapObjects ».

J'espère que quelqu'un est familier avec ceci et pourrait m'aider, merci d'avance! Cordialement, opx

+0

Vous avez sauvé ma journée avec cette question, merci! Je te dois une bière. – Matheno

Répondre

0

À première vue, il semble que le problème est que vous configurez votre WSDL en PHP afin que votre méthode getUserProfile() retourne un tableau d'objets UserProfile. En regardant la méthode, elle ne renvoie en réalité qu'un seul objet UserProfile ... et C# s'attend à ce qu'il s'agisse d'un tableau d'objets.

En résumé, votre fichier WSDL et votre code ne sont pas synchronisés. Je pense que vous devez modifier le code où vous enregistrez la méthode avec le WSDL:

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

Vous devez également modifier le code C# appeler le service Web à quelque chose comme ceci:

UserProfile user = service.getUserProfile(); 

Et puis vous pouvez vous débarrasser de l'enregistrement WSDL entier pour le type UserProfileArray.

0

J'ai eu le même problème, et c'était parce que j'essayais de créer un objet localement avec le même nom que l'objet renvoyé par le WebService. Ce que je devais faire à la place, était de permettre à la référence du service de gérer ce processus, et de définir l'objet pour moi, basé sur ce qu'il lisait du WSDL.

Ainsi, avec une référence de service appelé "localWS", puis applique:

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