Funkcja PHP WSDL zwraca wartość null, podczas gdy inna funkcja zwraca oczekiwany wynik

streszczenie

Tutaj wymienię wszystkie kroki, które podjąłem, aby rozwiązać ten problem jako odniesienie dla innych.

1. PHP, wystarczająco głupio, „słucha” komunikatu wejściowego funkcji, aby określić, jakiej funkcji powinien użyć. Daj więc każdej swojej funkcji inną wiadomość wejściową, nawet jeśli używa tego samego typu lub elementu. Możesz pomyśleć, że jest to trochę pracy do rozwiązania, ale można to zrobić w następujący sposób:

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

Następnie Visual Studio marudził, spędziłem kilka dni, zastanawiając się nad tą głupio idiotyczną prostą rzeczą, po prostu powiedz programowi, że właśnie ustawiłeś właściwość obiektów:

 UserCredentials.customerID = User.CustomerID;
 UserCredentials.customerIDSpecified = true;

I to wszystko. Nie mogę w to uwierzyć. Spędzam 1,5 tygodnia, rozwiązanie to dwa kroki, proszę dać temu koledze, który odpowiedział poniżej niektórych głosów.

Aktualizacja

Mój obiekt wejściowy NIE zaczyna się analizować w formacie XML.

//Naprawić:

Musisz powiedzieć programowi, że właściwość jest ustawiona tak:

UserCredentials.customerID = User.CustomerID;
UserCredentials.customerIDSpecified = true;

Skrzypek pokazuje to:

Wkład

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

Wydajność

<?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:E‌​nvelope>

Czy coś jest nie tak z tym kodem?

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

Aktualizacja do komentarza poniżej

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

Wydaje się, że działa, poza tym, że teraz zwraca tablicę count = 0 w VS10

Kolejna aktualizacja

W komentarzach ktoś napisałpołączyć do raportu o błędzie z PHP. Drugi ostatni komentator twierdził, że pracował nad tym samym problemem, który mam, umieszczając wszystkie defencje wiadomości w innych plikach i umieszczając je w tym głównym dokumencie WSDL. Próbowałem tego, ale to nie zadziałało, nic się nie zmieniło.

AKTUALIZACJA:

Zmieniłem więc kolejność funkcji zdefiniowanych w metodzie wiązania i zorientowałem się, że działa tylko pierwsza funkcja zdefiniowana w obszarze wiązania, więc w tym przypadku działa tylko moja getAllLessenData, ponieważ umieściłem ją ponad wszystkimi innymi. Czy ktoś widzi błąd?

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

koniec aktualizacji

Mam mały problem z WSLD (ponownie)

wszystkie moje getAllLessenData (i inne funkcje) zwracają NULL, podczas gdy jedna funkcja (getAllPersoonData) zwraca to, co jest oczekiwane.

Defencje tablic WSDL:

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

Definiowanie typów złożonych WSDL:

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

Definiowanie komunikatów WSDL:

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

Definiowanie typu portu WSDL

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

Definiowanie funkcji PHP:

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

co zwraca:

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)

W mojej bazie danych są wiersze i wywołanie getAllLessenData (1) bezpośrednio z mojego servicehandler.php zwraca oczekiwane wyniki. jednak w moim test.php po prostu zwraca NULL, a getLastResponse zwraca wyniki z getAllPersoonData (1).

Obie defencje funkcji wyglądają dla mnie tak samo, cholera, większość z nich skopiowałem. Próbowałem zmienić przestrzenie nazw itp. Google. ale to nie zadziałało. Jakieś pomysły?

Jeśli potrzebujesz więcej informacji, odpowiedz.

questionAnswers(1)

yourAnswerToTheQuestion