Die WSDL-PHP-Funktion gibt null zurück, während andere Funktionen das erwartete Ergebnis zurückgeben
Zusammenfassung
Hier liste ich alle Schritte auf, die ich unternommen habe, um dieses Problem zu lösen, als Referenz für andere.
1. PHP 'hört' dummerweise die Eingabenachricht einer Funktion ab, um zu definieren, welche Funktion es verwenden soll. Geben Sie jeder Ihrer Funktionen eine andere Eingabenachricht, obwohl sie denselben Typ oder dasselbe Element verwenden. Sie mögen denken, dass dies einige Arbeit ist, die Sie lösen müssen, aber es kann so gemacht werden:
<xsi:complexType name="UserCredentials">
<xsi:attribute name="customerID" type="xsi:int"/>
</xsi:complexType>
<xsi:element name="UserCredentials" type="types:UserCredentials"/>
<xsi:element name="UserCredentials1" type="types:UserCredentials"/>
<wsdl:message name="getCustomerCredentials">
<wsdl:part name="body" element="types:UserCredentials"/>
</wsdl:message>
<wsdl:message name="getCustomerCredentials1">
<wsdl:part name="body" element="types:UserCredentials1"/>
</wsdl:message>
Als nächstes jammerte Visual Studio, ich verbrachte ein paar Tage damit, diese blöde, idiotische, einfache Sache herauszufinden. Sagen Sie einfach dem Programm, dass Sie gerade die Eigenschaft objects gesetzt haben:
UserCredentials.customerID = User.CustomerID;
UserCredentials.customerIDSpecified = true;
Und das ist es. Ich kann es selbst nicht glauben. Ich verbringe 1,5 Wochen, die Lösung ist in zwei Schritten, bitte geben Sie diesem Typen, der unten geantwortet hat, einige Stimmen hoch.
Aktualisieren
Mein Eingabeobjekt wird NICHT in XML geparst.
//Fix:
Sie müssen dem Programm mitteilen, dass die Eigenschaft folgendermaßen festgelegt ist:
UserCredentials.customerID = User.CustomerID;
UserCredentials.customerIDSpecified = true;
Fiddler zeigt dies:
Eingang
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<UserCredentials2 xmlns="http://5.157.80.21/servicehandler/wsdl_service.wsdl"/>
</s:Body>
</s:Envelope>
Ausgabe
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="types">
<SOAP-ENV:Body>
<ns1:PersoonArray/>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
Stimmt etwas mit diesem Code nicht?
public static List<Klant> GetAllPersonen()
{
List<Klant> list = new List<Klant>();
WeGotchaService.Persoon[] servicePersonen = dpc.getAllPersoonData(UserCredentials);
foreach (WeGotchaService.Persoon p in servicePersonen)
{
Klant k = new Klant(p);
list.Add(k);
}
return list;
}
Update auf Kommentar unten
<xsi:complexType name="UserCredentials">
<xsi:attribute name="customerID" type="xsi:int"/>
</xsi:complexType>
<xsi:element name="UserCredentials" type="tns:UserCredentials" />
<xsi:element name="UserCredentials2" type="tns:UserCredentials"/>
<wsdl:message name="getCustomerCredentials">
<wsdl:part name="body" element="ns:UserCredentials"/>
</wsdl:message>
<wsdl:message name="getCustomerCredentials2">
<wsdl:part name="body" element="ns:UserCredentials2"/>
</wsdl:message>
<wsdl:operation name="getAllLessenData">
<wsdl:input message="ns:getCustomerCredentials"/>
<wsdl:output message="ns2:LessenList"/>
</wsdl:operation>
<wsdl:operation name="getAllPersoonData">
<wsdl:input message="ns:getCustomerCredentials2"/>
<wsdl:output message="ns3:PersoonList"/>
</wsdl:operation>
Dies scheint zu funktionieren, außer dass jetzt ein count = 0-Array in VS10 zurückgegeben wird
Noch ein Update
In den Kommentaren hat jemand eineVerknüpfung zu einem Fehlerbericht mit PHP. Der vorletzte Kommentator behauptete, dass er das gleiche Problem, das ich habe, umgangen habe, indem er alle Nachrichtenverteidigungen in andere Dateien gestellt und sie in dieses Haupt-WSDL-Dokument aufgenommen hat. Ich habe es versucht, aber es hat nicht funktioniert, nichts hat sich geändert.
AKTUALISIEREN:
Daher habe ich die Reihenfolge der in der Bindungsmethode definierten Funktionen geändert und Folgendes herausgefunden: Nur die erste im Bindungsbereich definierte Funktion funktioniert. In diesem Fall funktioniert also nur meine getAllLessenData, weil ich sie über die anderen stelle. Kann jemand einen Fehler sehen?
<wsdl:binding name="DataBinding" type="tns:DataPort">
<soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
<wsdl:operation name="getAllLessenData">
<soap:operation soapAction="" style="document"/>
<wsdl:input>
<soap:body use="literal"/>
</wsdl:input>
<wsdl:output>
<soap:body use="literal"/>
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="getAllPersoonData">
<soap:operation soapAction="" style="document"/>
<wsdl:input>
<soap:body use="literal"/>
</wsdl:input>
<wsdl:output>
<soap:body use="literal"/>
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="getAllBetalingData">
<soap:operation soapAction="" style="document"/>
<wsdl:input>
<soap:body use="literal"/>
</wsdl:input>
<wsdl:output>
<soap:body use="literal"/>
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="getPersoonLessenData">
<soap:operation soapAction="" style="document"/>
<wsdl:input>
<soap:body use="literal"/>
</wsdl:input>
<wsdl:output>
<soap:body use="literal"/>
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="getPersoonBetalingenData">
<soap:operation soapAction="" style="document"/>
<wsdl:input>
<soap:body use="literal"/>
</wsdl:input>
<wsdl:output>
<soap:body use="literal"/>
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
Ende der Aktualisierung
Ich habe (wieder) ein kleines Problem mit der WSLD
Meine getAllLessenData (und andere Funktionen) geben alle NULL zurück, während eine Funktion (getAllPersoonData) das zurückgibt, was erwartet wird.
WSDL Array Defenitionen:
<xsi:element name="PersoonArray">
<xsi:complexType>
<xsi:sequence>
<xsi:element name="Persoon" type="tns:Persoon" maxOccurs="unbounded"/>
</xsi:sequence>
</xsi:complexType>
</xsi:element>
<xsi:element name="LessenArray">
<xsi:complexType>
<xsi:sequence>
<xsi:element name="Les" type="tns:Les" maxOccurs="unbounded"/>
</xsi:sequence>
</xsi:complexType>
</xsi:element>
WSDL complexType-Definitionen:
<xsi:complexType name="Les">
<xsi:attribute name="ID" type="xsi:int"/>
// lots of stuff //
<xsi:attribute name="Definitief" type="xsi:boolean"/>
</xsi:complexType>
<xsi:complexType name="Persoon">
<xsi:attribute name="ID" type="xsi:int"/>
<// lots of stuff //
<xsi:attribute name="Laatste_keer_bewerkt" type="xsi:dateTime"/>
</xsi:complexType>
WSDL-Nachrichtenverteidigungen:
<wsdl:message name="getCustomerID">
<wsdl:part name="CustomerID" type="xs:int"/>
</wsdl:message>
<wsdl:message name="PersoonList">
<wsdl:part name="PersoonList" element="tns:PersoonArray"/>
</wsdl:message>
<wsdl:message name="LessenList">
<wsdl:part name="LessenList" element="tns:LessenArray"/>
</wsdl:message>
WSDL-PortType-Definition
<wsdl:operation name="getAllPersoonData">
<wsdl:input message="tns:getCustomerID"/>
<wsdl:output message="tns:PersoonList"/>
</wsdl:operation>
<wsdl:operation name="getAllLessenData">
<wsdl:input message="tns:getCustomerID"/>
<wsdl:output message="tns:LessenList"/>
</wsdl:operation>
WSDL Binding Defention
<soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
<wsdl:operation name="getAllPersoonData">
<soap:operation soapAction="http://localhost/weGotcha/servicehandler/servicehandler.php" style="document"/>
<wsdl:input>
<soap:body use="literal"/>
</wsdl:input>
<wsdl:output>
<soap:body use="literal"/>
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="getAllLessenData">
<soap:operation soapAction="http://localhost/weGotcha/servicehandler/servicehandler.php" style="document"/>
<wsdl:input>
<soap:body use="literal"/>
</wsdl:input>
<wsdl:output>
<soap:body use="literal"/>
</wsdl:output>
</wsdl:operation>
PHP Funktionsdefinitionen:
function getAllPersoonData($customer_ID)
{
connectToDB();
//////////// yes I use mysqli now /////////////
$sql = "SELECT * FROM personen WHERE Customer_ID='". $customer_ID ."'";
$sql = mysql_query($sql) or die(mysql_error());
$result = array();
while($row = mysql_fetch_array($sql))
{
$row["Kosten_totaal"] = mysql_fetch_array(mysql_query("SELECT SUM(Kosten) FROM lessen WHERE Persoon_ID='". $row["ID"] ."'"))[0];
$row["Totaal_betaald"] = mysql_fetch_array(mysql_query("SELECT SUM(Bedrag) FROM betalingen WHERE Persoon_ID='". $row["ID"] ."'"))[0];
$lkbDatum = strtotime($row["Laatste_keer_bewerkt"]);
$row["Laatste_keer_bewerkt"] = date("Y-m-d", $lkbDatum) . "T". date("H:i:s", $lkbDatum);
$result[] = $row;
}
mysql_close();
return $result;
}
function getAllLessenData($customer_ID)
{
$sql = "SELECT * FROM lessen WHERE Customer_ID='". $customer_ID ."'";
//////////// yes I use mysqli now /////////////
connectToDB();
$sql = mysql_query($sql) or die(mysql_error());
$result = array();
while($row = mysql_fetch_array($sql))
{
$result[] = $row;
}
mysql_close();
return $result;
}
$server = new SoapServer("wsdl_service.wsdl");
$server->AddFunction("getAllPersoonData");
$server->AddFunction("getAllBetalingData");
$server->AddFunction("getPersoonBetalingData");
$server->AddFunction("getAllLessenData");
$server->AddFunction("getPersoonLessenData");
$server->handle();
Test.php
$client = new SoapClient("http://localhost/weGotcha/servicehandler/wsdl_service.wsdl", array("trace" => 1));
var_dump($client->__getFunctions());
var_dump($client->getAllLessenData(1));
var_dump($client->__getLastRequest());
var_dump($client->__getLastResponse());
was zurückgibt:
array (size=5)
0 => string 'PersoonArray getAllPersoonData(int $CustomerID)' (length=47)
1 => string 'LessenArray getAllLessenData(int $CustomerID)' (length=45)
2 => string 'BetalingenArray getAllBetalingData(int $CustomerID)' (length=51)
3 => string 'LessenArray getPersoonLessenData(int $getCustomerID, int $getPersoonID)' (length=71)
4 => string 'BetalingenArray getPersoonBetalingenData(int $getCustomerID, int $getPersoonID)' (length=79)
null
string '<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"><SOAP-ENV:Body><CustomerID>1</CustomerID></SOAP-ENV:Body></SOAP-ENV:Envelope>
' (length=195)
string '<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://localhost/weGotcha/servicehandler/wsdl_service.wsdl"><SOAP-ENV:Body> <ns1:PersoonArray><ns1:Persoon ID="1" Voornaam="xxxx" Achternaam="xxxx" Adres="xxxx" Postcode="xxxx" Woonplaats="xxxx" Email_adres="xxxx" Telefoonnummer="xxxx" Geboortedatum="0001-01-01" CBR_kandidaatnummer="12381233" Rijbewijs="2" Theorie_behaald="false" Theorie_po'... (length=3096)
In meiner Datenbank befinden sich Zeilen, und der Aufruf von getAllLessenData (1) direkt aus meiner servicehandler.php gibt die erwarteten Ergebnisse zurück. In meiner test.php gibt es jedoch einfach NULL zurück und die getLastResponse gibt die Ergebnisse von getAllPersoonData (1) zurück.
Beide Funktionsdefinitionen sehen für mich gleich aus, obwohl ich das meiste davon kopiert habe. Ich habe versucht, Namespaces usw. Google zu ändern. aber es hat nicht funktioniert. Irgendwelche Ideen?
Wenn Sie weitere Informationen benötigen, antworten Sie bitte.