Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   XML (https://www.delphipraxis.net/46-xml/)
-   -   Delphi Generic List über SOAP (https://www.delphipraxis.net/150579-generic-list-ueber-soap.html)

Postman1986 21. Apr 2010 08:50


Generic List über SOAP
 
Hi,

ich möchte gern einen Delphi basierten Dienst schreiben, der einige Methoden bereitstellt die von einem C# Client aus genutzt werden können.

Dazu habe ich einen SOAP Server in Delphi erstellt der den Webservice anbietet. Das funktioniert soweit ganz gut, die vorgenerierten Testmethoden wie EchoDouble etc. können ohne Probleme in C# importiert und genutzt werden, mein Problem tritt jetzt beim Versuch auf, eine generische Liste zu exportieren.

Der Delphi Server erstellt zwar ohne zu zögern die wsdl Datei, Visual Studio bemängelt beim Import dann aber die "<" und ">" Tags der generic List Deklaration (was hinsichtlich validem XMLs ja auch sein gutes Recht ist).

Die Frage ist nun, wie man eine generische Liste sauber über SOAP exportieren kann.


Hier die Implementation der Delphi Server Funktion:
Delphi-Quellcode:
function TJamSOAPWebService.GenericList(const Value: TList<string>): TList<string>; stdcall;
var
  myString: string;
begin
  myString := 'Hey :)';
  Value.Add(myString);
  Result := Value;
end;

Der generierte XML Code (relevanter Teil):
XML-Code:
<types>
&#8722;
<xs:schema targetNamespace="urn:JamSOAPWebServiceIntf">
&#8722;
<xs:simpleType name="TEnumTest">
&#8722;
<xs:restriction base="xs:string">
<xs:enumeration value="etNone"/>
<xs:enumeration value="etAFew"/>
<xs:enumeration value="etSome"/>
<xs:enumeration value="etAlot"/>
</xs:restriction>
</xs:simpleType>
&#8722;
<xs:complexType name="TDoubleArray">
&#8722;
<xs:complexContent>
&#8722;
<xs:restriction base="soapenc:Array">
<xs:sequence/>
<xs:attribute ref="soapenc:arrayType" n1:arrayType="xs:double[]"/>
</xs:restriction>
</xs:complexContent>
</xs:complexType>
&#8722;
<xs:complexType name="TMyEmployee">
&#8722;
<xs:sequence>
<xs:element name="LastName" type="xs:string"/>
<xs:element name="FirstName" type="xs:string"/>
<xs:element name="Salary" type="xs:double"/>
</xs:sequence>
</xs:complexType>
&#8722;
<xs:complexType name="TList<System.string>">
&#8722;
<xs:complexContent>
&#8722;
<xs:extension base="TEnumerable<System.string>">
<xs:sequence/>
</xs:extension>
</xs:complexContent>
</xs:complexType>
</xs:schema>
&#8722;
<xs:schema targetNamespace="urn:Classes">
&#8722;
<xs:complexType name="TList">
<xs:sequence/>
</xs:complexType>
</xs:schema>
</types>

Der Fehler:
Code:
Error: Invalid 'name' attribute value 'TList<System.string>': 'The '<' character, hexadecimal value 0x3C, at position 5 within the name, cannot be included in a name.'.

Gruß Daniel

himitsu 21. Apr 2010 09:04

Re: Generic List über SOAP
 
In XML muß <, > als &lt; und &gt; maskiert sein.
Anscheinend führt SOAP keine entsprechende Konvertierung, beim Zusammenbau der XML-Datei aus.
(Vor den Generics gab es auch keinen Grund dafür, da entsprechende Zeichen eh nicht in Typenbezeichnungen erlaubt waren.)

PS: Definier dir auch besser noch TList<string> als eigenständigen Typen und verwende diesen Typen, anstatt den generischen Typen jedesmal neu zu erstellen.
(Sowas ist, Aufgrund der strengen Typenprüfung seitens Delphi, etwas besser.)
Delphi-Quellcode:
TMyStringList = TList<string>;
PS: Warum nicht direkt eine TStringList/TStrings?

Postman1986 21. Apr 2010 09:17

Re: Generic List über SOAP
 
Mir wurde die Aufgabe zugetragen, einen möglichst generischen Ansatz zu verfolgen, um später auch andere Objekte mit Hilfe des Interfaces übergeben zu können.

Die Maskierung kam mir auch in den Sinn, mir ist nur nicht klar wie ich den Delphi Compiler dazu veranlassen kann statt der "Tag-Zeichen" den jeweiligen Code zu benutzen.

Danke für den Tip mit der Typenprüfung.

himitsu 21. Apr 2010 09:27

Re: Generic List über SOAP
 
Mal ganz ehrlich ...

SOAP ist in der Hinsicht ein bissl "schrottig", da es die XML-Datei "selber" aus Strings und nicht über eine (ordentliche) XML-Lib zusammenbaut.
Das Auslesen geschieht aber dennoch über einen XML-Parser, welcher dann über die ungültige XML-Datei rummotzt und den Dienst verweigert.
(XML-Parser sollen, laut Spezifikation, bei sowas den Vorgang abbrechen ... ein Reparaturmodus, so wie bei einem HTML-Parser, ist nicht vorgesehn)


Tja, das Einzige was du da machen könntest wäre warten, bis Emba auf eine QC-Meldung (solltest besser mal Eine einreichen) reagiert, aber das kann Jahre dauern, falls überhaupt was passiert.
(wie man sieht http://www.delphipraxis.net/internal...146020#1146020 )

Ansonsten blieben dir nur 2 Möglichkeiten:
- auf Generics verzichten
- oder alle Stellen in den vielen SOAP-Units suchen und diese Konvertierung selber einbauen,
aka versuchen die Delphi-QuellCodes zu ändern und danach die abhängigen Units, inkl. der Packages, neu zu kompilieren.


[add]
Falls du das SOAP dazu bringen könnest, daß es die Vorfahren deines Types nicht mit auflistet, dann könntest du den generischen Typen zumindestens kapseln und somit die bösen < und > nicht in der XML-Datei auftauchen lassen.
Delphi-Quellcode:
type TMyList = class(TList<string>) end;

function TJamSOAPWebService.GenericList(const Value: TMyList): TMyList; stdcall;

Postman1986 21. Apr 2010 10:22

Re: Generic List über SOAP
 
Vielen Dank für den Ansatz, leider hat die Kapselung allerdings auch keine Auswirkung auf den XML Parser, die Tags werden nach wie vor mit reingepackt.

Hat mir aber schon weitergeholfen! Jetzt weiß ich wenigstens, dass es so ohne Weiteres nicht möglich ist Generics zu benutzen. Ich weiche dann erstmal auf StringList bzw. eigene Objekte mit nativen Datentypen aus.

Falls dann später irgendwer unbedingt noch Objekte mitübergeben möchte, die hiermit nicht abgebildet werden können, kann man sich ja nochmal mit dem Thema auseinandersetzen (vlt. geht Emba mit zunehmender WCF Verbreitung ja auch noch einen Schritt in diese Richtung).


Alle Zeitangaben in WEZ +1. Es ist jetzt 11:21 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz