2009-07-16 10 views
1

Ich versuche, einen Client in C# zu erstellen, der mit einem entfernten (php) Server mit SOAP über die NuSOAP-Bibliothek kommuniziert. hier im ein struct/Objekt verwendet, das dem Benutzer Informationen einiger Benutzer containt wird:C# struct und 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;

Und das ist die PHP-Code: Ich habe

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; 
}

nun bereits eine funktionierende Login-Funktion, und ich Ich möchte die Informationen über den angemeldeten Benutzer erhalten, aber ich weiß nicht, wie ich diese beschaffen kann. Dies ist, was im der Userinfo erhalten mit:

   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);

Die getUserProfile() Funktion erzeugt einen Fehler:

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

oder ich so etwas wie 'kann nicht Parse xml' Fehler.

Der Artikel, den ich für diese verwendet wurde von: http://www.sanity-free.org/125/php_webservices_and_csharp_dotnet_soap_clients.html Der Unterschied auf, was sie tun und was ich versuche zu tun, dass ich nur ein Objekt zurückgegeben anstelle von mehreren ‚MySoapObjects‘ erhalten möchten.

Ich hoffe jemand ist damit vertraut und könnte mir helfen, danke im Voraus! Grüße, opx

+0

Sie sparte meinen Tag mit dieser Frage, danke! Ich schulde dir ein Bier. – Matheno

Antwort

0

Auf den ersten Blick scheint das Problem, dass Sie Ihre WSDL in PHP einrichten, so dass Ihre getUserProfile() -Methode ein Array von UserProfile-Objekten zurückgibt. Wenn Sie sich die Methode ansehen, wird nur ein einzelnes UserProfile-Objekt zurückgegeben ... und C# erwartet, dass es sich um ein Array von Objekten handelt.

Kurz gesagt, Ihre WSDL und der Code sind nicht synchron. Ich glaube, Sie müssen den Code ändern, in dem Sie die Methode mit dem WSDL registrieren:

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

Du musst auch den C# -Code ändern, um den Web-Service zu so etwas wie dieser Aufruf:

UserProfile user = service.getUserProfile(); 

Und dann können Sie die gesamte WSDL-Registrierung für den UserProfileArray-Typ loswerden.

0

Ich hatte das gleiche Problem, und es war, weil ich versuchte, ein Objekt lokal mit dem gleichen Namen wie das Objekt zu erstellen, das vom WebService zurückgegeben wird.

Was ich stattdessen tun musste, war, der Service-Referenz diesen Prozess zu verwalten und das Objekt für mich zu definieren, basierend auf dem, was es aus der WSDL gelesen hat.

mit einer Service-Referenz So genannten "localWS", dann gilt:

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