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 :

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
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
 
<Criteres_liste>
   <crit id="1">test1</crit>
   <crit id="2">test2</crit>
   <crit id="3">test3</crit>
</Criteres_liste>
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.

En utilisant WebServiceStudio afin de tracer les échanges SOAP d'un web service, je reçois bien

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

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