Laden...

SOAP Complex Type Probleme

Erstellt von bonzy vor 10 Jahren Letzter Beitrag vor 10 Jahren 4.195 Views
bonzy Themenstarter:in
157 Beiträge seit 2008
vor 10 Jahren
SOAP Complex Type Probleme

Hallo zusammen,

ich hänge jetzt seit ein paar Tagen an diesem Problem und komme nicht mehr wirklich weiter. Ich habe bereits viele Kombinationen an Stichwörtern durch Google gejagt, aber sobald es in die Nähe meines Problems kam, gab es keine Antworten mehr.

Ich möchte anhand eines SOAP-Service Daten einer Website abfragen. Dazu habe ich eine Web Reference meinem Projekt hinzugefügt und greife darüber auf die Methoden zu. Dies funktioniert für simple Types wunderbar, sobald ein Complex Type ins Spiel kommt, fange ich mir alle möglichen Exceptions.

Beispielsweise liefert eine Methode getuserids(int) einen Typ ArrayOfUserid zurück. Dieser beinhaltet wiederum ein int[]. Beim Ausführen fange ich mir jedoch eine InvalidCastException > Fehlermeldung:

Ein Objekt des Typ System.Int32[] kann nicht einem Objekt des Typs ArrayOfUserid zugewiesen werden. . Wenn ich die generierte Reference.cs entsprechend verändere, dass die Methode direkt ein int[] zurückliefert, funktioniert es. Das gilt für jeden Array-Typ.

Sobald eine Methode mit einem "einfachen" sprich nicht-Array-Typ aufgerufen wird (z.B. getplayerbyid(int)), gibt es Exceptions wie > Fehlermeldung:

Ein Objekt des Typ System.Xml.XmlNode[] kann nicht einem Objekt des Typs Player zugewiesen werden. oder > Fehlermeldung:
Der angegebene Typ wurde nicht erkannt: Name='Map', Namespace='http://xml.apache.org/xml-soap', bei <return xmlns=''>.

Ich verwende diese WSDL: http://www.comunio.de/soapservice.php?wsdl

Da sich die Reference.cs leicht generieren lässt, kopiere ich den Code jetzt nicht nochmal hierhin. Ich verwende dazu VS8. Ich habe es wie oben angesprochen über Visual Studio generieren lassen, da sind soweit ich das überschaut habe keine Parameter anzugeben.

Unter Java ließ sich das Problem für die Array-Typen laut einem Kollegen lösen, indem über eine Option beim Generieren durch AXIS1 das Unwrapping aktiviert wurde.

Hier noch der Code zum Ausführen:


            soapservicewsdl soap = new soapservicewsdl();

            object o = soap.getuserids(1458132);

Ich bin recht unerfahren was das Thema anbelangt, daher für jede Hilfe offen. 😃 Für mehr Informationen einfach anfragen.

Schönen Gruß

Edit: Mit dem Tool soapUI konnte ich mir verschiedene Response-XMLs anschauen und bin zumindest mal auf den Typ "Map" gestoßen, der aus dem namespace http://xml.apache.org/xml-soap entstammt. Gibt es eventuell damit bekannte Probleme?

<SOAP-ENV:Envelope SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="urn:soapservicewsdl" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:ns2="http://xml.apache.org/xml-soap" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/">
   <SOAP-ENV:Body>
      <ns1:getplayerbyidResponse>
         <return xsi:type="ns2:Map">
            <item>
               <key xsi:type="xsd:string">id</key>
               <value xsi:type="xsd:int">31080</value>
            </item>
            <item>
               <key xsi:type="xsd:string">name</key>
               <value xsi:type="xsd:string">Blaszczykowski</value>
            </item>
            <item>
               <key xsi:type="xsd:string">points</key>
               <value xsi:type="xsd:int">159</value>
            </item>
            <item>
               <key xsi:type="xsd:string">clubid</key>
               <value xsi:type="xsd:int">5</value>
            </item>
            <item>
               <key xsi:type="xsd:string">quote</key>
               <value xsi:type="xsd:int">9060000</value>
            </item>
            <item>
               <key xsi:type="xsd:string">status</key>
               <value xsi:type="xsd:string">ACTIVE</value>
            </item>
            <item>
               <key xsi:type="xsd:string">position</key>
               <value xsi:type="xsd:string">midfielder</value>
            </item>
         </return>
      </ns1:getplayerbyidResponse>
   </SOAP-ENV:Body>
</SOAP-ENV:Envelope>
6.911 Beiträge seit 2009
vor 10 Jahren

Hallo bonzy,

mit PHP-SOAP-Services gibt es oft Probleme, kannst ja mal im Forum danach suchen.

Einen direkten Tipp zur Lösung des Problems hab ich leider nicht, aber schau dir mal das Tool svcutil.exe an. Dort hast du weit mehr Einstellmöglichkeiten als aus VS heraus. Es gibt auch einen /wrapped-Schalter - vllt. hilft dieser schon.

mfG Gü

Stellt fachliche Fragen bitte im Forum, damit von den Antworten alle profitieren. Daher beantworte ich solche Fragen nicht per PM.

"Alle sagten, das geht nicht! Dann kam einer, der wusste das nicht - und hat's gemacht!"

bonzy Themenstarter:in
157 Beiträge seit 2008
vor 10 Jahren

Hallo gfoidl,

danke für die Antwort. Ich habe mir das Tool angeschaut und verschiedene Parameter ausprobiert. Die generierten Dateien brachten allerdings keine Lösung. Weitere Suchen nach dem Problem sagten mir ebenfalls nur, dass es "schwierig" ist. Gibt es eventuell eine andere, meinetwegen manuellere Methode? Im dümmsten Fall muss ich wohl hingehen und die XML-Responses direkt abfangen und selber parsen.

Gruß
bonzy

W
955 Beiträge seit 2010
vor 10 Jahren

Hast Du mal geschaut ob es mit den alten Serviceproxies besser läuft?

Add Service Reference => Advanced => Add Web Reference

bonzy Themenstarter:in
157 Beiträge seit 2008
vor 10 Jahren

Hast Du mal geschaut ob es mit den alten Serviceproxies besser läuft?

Add Service Reference => Advanced => Add Web Reference

Da ich in VS8 arbeite, habe ich die alte natürlich probiert. Das neue wurde Testweise auch ausprobiert, aber ohne Besserung.

6.911 Beiträge seit 2009
vor 10 Jahren

Hallo bonzy,

Gibt es eventuell eine andere, meinetwegen manuellere Methode?

Du könntest anhand des WSDL selbst die Client-Klassen erstellen und über die OperationContract-Attribute die entsprechende Action (aus dem WSDL) setzen.

Sollte auch das nicht klappen, so könntest du noch bei der (De-) Serialisierung von WCF einhaken und dort die korrekten Typen zurückgeben (ganz grob via IXmlSerializable).

Eine ganz andere Möglichkeit wäre, dass du einen "Wrapper-PHP-Service" erstellst, den dein Client aufrufen kann und dieser PHP-Service den anderen aufruft. Ich weiß jetzt nicht wie fit du in PHP bist, aber vllt. kommst du damit schneller zum Ziel.

mfG Gü

Stellt fachliche Fragen bitte im Forum, damit von den Antworten alle profitieren. Daher beantworte ich solche Fragen nicht per PM.

"Alle sagten, das geht nicht! Dann kam einer, der wusste das nicht - und hat's gemacht!"

bonzy Themenstarter:in
157 Beiträge seit 2008
vor 10 Jahren

Hey gfoidl,

das Einhaken bei der Serialisierung klingt recht vielversprechend. Hast du da eventuell noch eine Quelle zu parat?

Gruß

6.911 Beiträge seit 2009
vor 10 Jahren

Hallo bonzy,

WCF Extensibility – Serialization und WCF Extensibility – Serialization Callbacks (ev. die anderen Punkte auf der Übersichtseite unter 3 auch).

mfG Gü

Stellt fachliche Fragen bitte im Forum, damit von den Antworten alle profitieren. Daher beantworte ich solche Fragen nicht per PM.

"Alle sagten, das geht nicht! Dann kam einer, der wusste das nicht - und hat's gemacht!"