Bonjour,
Je suis en train de développer un service web dont l'une des méthodes doit me retourner une collections de (clé - valeur). J'ai opté pour un objet NameValueCollection.
Le problème est que cet object NameValueCollection refuse d'être utilisé en tant que retour d'une methode web pour un problème de sérialisation. Bref, peu importe, je décide alors de créer ma propre classe sérialisable (qui implément IXmlSerialisaable), la voici :
Comme vous l'avez compris, j'encapsule dans une classe sérialisable une NameValueCollection ce qui me permet de contrôler la façon dont-il sera sérialisé. Ici je souhaite que mon NameValueCollection soit sérialisé ainsi :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48 <Serializable> _ public class Criteres_liste Implements IXmlSerializable private properties as NameValueCollection public sub New() End sub public sub new(properties as NameValueCollection) Me.properties = properties End sub <XmlIgnore> _ Public Property Prop As NameValueCollection Get Return Me.properties End Get Set(ByVal Value As NameValueCollection) Me.properties = Value End Set End Property Function GetSchema() as System.Xml.Schema.XmlSchema Implements IXmlSerializable.GetSchema return nothing End Function sub ReadXml(reader as XmlReader) Implements IXmlSerializable.ReadXml Me.properties = new NameValueCollection() While (reader.MoveToNextAttribute()) Me.properties.Add(reader.Name, reader.Value) end while reader.Read() end sub sub WriteXml(writer as XmlWriter) Implements IXmlSerializable.WriteXml for each key as string in Me.properties.Keys writer.WriteStartElement("crit") dim value as string = Me.properties(key) writer.WriteAttributeString("id", key) writer.WriteValue(value) writer.WriteEndElement() next end sub End class
Maintenant, ma méthode web retourne un objet Criteres_liste et lorsque je teste mon webservice en executant directement le fichier .asmx, je reçois bien le code XML ci-dessus dans mon navigateur.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6 <Criteres_liste> <crit id="1">test1</crit> <crit id="2">test2</crit> <crit id="3">test3</crit> </Criteres_liste>
En utilisant WebServiceStudio afin de tracer les échanges SOAP d'un web service, je reçois bien
Tout ceci me plait bien. Je décide donc de m'attaquer au client. Pour celà j'utilise l'exe WDSL.EXE. Celui-ci me génère une classe proxy que je compile en DLL.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13 <?xml version="1.0" encoding="utf-16"?> <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <soap:Body> <ListeEquivalenceResponse xmlns="http://www.toto.fr/"> <ListeEquivalenceResult> <crit id="1">test1</crit> <crit id="2">test2</crit> <crit id="3">test3</crit> </ListeEquivalenceResult> </ListeEquivalenceResponse> </soap:Body> </soap:Envelope>
Je l'instancie, j'appelle ma méthode web et là, Ô surprise, le retour de la méthode en question qu'il attend est en fait un DataSet ...
Et effectivement, lorsque je regarde dans le code généré par le WSDL.EXE je constate bien que le retour de ma métode web est un DataSet.
Soit, si je caste le résultat en DataSet celui est vide. Je n'arrive pas a récupérer mes résultat (alors qu'il y a bien qque chose dans la réponse).
Je voudrais savoir si il y a un moyen de faire en sorte que WSDL.EXE génère le bon code (mais en réfléchissant, ce dernier n'a aucune connaissance de ma classe liste_critère) ou bien y a t-il qque chose à faire pour que le dataset de sortie soit bien rempli?
Un autre moyen plus compliqué serait de passer par un HttpWebRequest est de décortiquer le SOAP à la main afin de récupérer la portion de XML qui m'intéresse. Mais on perd la souplesse offerte par WSDL.EXE
Ceci me fait me poser les questions suivantes :
-WDSL.exe ne fonctionne t-il qu'avec des types simples?
-Si je fais un web service qui me retourne un DataSet, mon client .net arrive bien a le récupérer (car le dataset est un type ".net"), mais qu'en sera t-il pour un client écrit en PhP ou en ColdFusion? Pour une désérialisation adéquat ne faut-il pas que le client ait connaissant de la classe cible? Or en Php ou coldFusion le dataset n'existe pas.
J'espère avoir été assez clair et pas trop long ^^
Merci de m'éclairer sur ces points
Partager