Lecture de réponse de service retournant un objet complexe
Bonjour !
Je bloque sur un gros problème d'appel de service retournant un objet complexe, voici une partie du wsdl :
Code:
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
|
<xsd:complexType name="AGDungeonSoapArrayAssociation">
<xsd:sequence>
<xsd:element name="key" type="xsd:string"/>
<xsd:element name="value" type="xsd:string"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="AGDungeonSoapArray">
<xsd:sequence>
<xsd:element name="items" minOccurs="0" maxOccurs="unbounded" type="xsd1:AGDungeonSoapArrayAssociation"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="AGDungeonSoapMETA">
<xsd:sequence>
<xsd:element minOccurs="0" maxOccurs="1" name="data" type="xsd1:AGDungeonSoapArray"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="AGDungeonSoapREAD">
<xsd:sequence>
<xsd:element minOccurs="0" maxOccurs="unbounded" name="data" type="xsd1:AGDungeonSoapArray"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="AGDungeonSoapERROR">
<xsd:sequence>
<xsd:element minOccurs="0" maxOccurs="unbounded" name="data" type="xsd1:AGDungeonSoapArray"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="AGDungeonSoapResponse">
<xsd:all>
<xsd:element name="META" type="xsd1:AGDungeonSoapMETA"/>
<xsd:element name="READ" type="xsd1:AGDungeonSoapREAD"/>
<xsd:element name="ERROR" type="xsd1:AGDungeonSoapERROR"/>
</xsd:all>
</xsd:complexType>
...
<wsdl:message name="RegisterResponse">
<wsdl:part name="response" type="xsd1:AGDungeonSoapResponse"/>
</wsdl:message>
<wsdl:message name="RegisterRequest">
<wsdl:part name="command" type="xsd:string"/>
<wsdl:part name="parameters" type="xsd1:AGDungeonSoapArray"/>
<wsdl:part name="options" type="xsd1:AGDungeonSoapArray"/>
</wsdl:message> |
Le but est de consommer la méthode Register du service, en exécutant la commande PING comme indique le message soap suivant et sa réponse :
Requête :
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:dun="http://adresse_du_serveur">
<soapenv:Header/>
<soapenv:Body>
<dun:Register>
<command>PING</command>
<parameters>
<items>
<key>dac</key>
<value>AGWk4wm3l30n3l4h</value>
</items>
</parameters>
<options>
<items>
<key>?</key>
<value>?</value>
</items>
</options>
</dun:Register>
</soapenv:Body>
</soapenv:Envelope> |
Réponse :
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
|
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Body>
<SOAP-ENV:RegisterResponse>
<response>
<META>
<data>
<items>
<key>ping</key>
<value>1</value>
</items>
</data>
</META>
<READ/>
<ERROR/>
</response>
</SOAP-ENV:RegisterResponse>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope> |
J'essaye de réaliser cela en c# : j'ai généré le fichier reference.cs depuis le wsdl, voici les parties concernées de son contenu : (désolé d'être long mais j'essaie de fournir le maximum d'infos possible)
Code:
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 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87
|
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.Xml", "2.0.50727.3053")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(Namespace="*******************]
public partial class AGDungeonSoapResponse {
private AGDungeonSoapMETA mETAField;
private AGDungeonSoapArrayAssociation[][] rEADField;
private AGDungeonSoapArrayAssociation[][] eRRORField;
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
public AGDungeonSoapMETA META {
get {
return this.mETAField;
}
set {
this.mETAField = value;
}
}
....
public partial class AGDungeonSoapMETA {
private AGDungeonSoapArrayAssociation[] dataField;
/// <remarks/>
[System.Xml.Serialization.XmlArrayAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
[System.Xml.Serialization.XmlArrayItemAttribute("items", Form=System.Xml.Schema.XmlSchemaForm.Unqualified, IsNullable=false)]
public AGDungeonSoapArrayAssociation[] data {
get {
return this.dataField;
}
set {
this.dataField = value;
}
}
}
...
public partial class AGDungeonSoapArrayAssociation {
private string keyField;
private string valueField;
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
public string key {
get {
return this.keyField;
}
set {
this.keyField = value;
}
}
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
public string value {
get {
return this.valueField;
}
set {
this.valueField = value;
}
}
}
....
[System.Web.Services.Protocols.SoapRpcMethodAttribute("capeconnect:dungeonsoap:dungeonsoapPortType#Register", RequestNamespace="", ResponseNamespace="", Use=System.Web.Services.Description.SoapBindingUse.Literal)]
[return: System.Xml.Serialization.XmlElementAttribute("response")]
public AGDungeonSoapResponse Register(string command, [System.Xml.Serialization.XmlArrayItemAttribute("items", Form=System.Xml.Schema.XmlSchemaForm.Unqualified, IsNullable=false)] AGDungeonSoapArrayAssociation[] parameters, [System.Xml.Serialization.XmlArrayItemAttribute("items", Form=System.Xml.Schema.XmlSchemaForm.Unqualified, IsNullable=false)] AGDungeonSoapArrayAssociation[] options) {
object[] results = this.Invoke("Register", new object[] {
command,
parameters,
options});
return ((AGDungeonSoapResponse)(results[0]));
} |
Dans mon code, j'essaie d'appeler la méthode Register en passant les paramètres comme défini dans la signature, et puis sérialiser la réponse (AGDungeonSoapResponse) dans un fichier XML, voici mon code :
Code:
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
|
Console.WriteLine("Appel du service en cours...");
dungeonsoap dsoap = new dungeonsoap();
AGDungeonSoapResponse response = new AGDungeonSoapResponse();
AGDungeonSoapArrayAssociation[] parametrs = new AGDungeonSoapArrayAssociation[1];
AGDungeonSoapArrayAssociation[] options = new AGDungeonSoapArrayAssociation[1];
parametrs[0] = new AGDungeonSoapArrayAssociation();
parametrs[0].key = "dac";
parametrs[0].value = "AGWk4wm3l30n3l4h";
options[0] = new AGDungeonSoapArrayAssociation();
options[0].key = "?";
options[0].value = "?";
response.META = new AGDungeonSoapMETA();
response.META.data = new AGDungeonSoapArrayAssociation[1];
response.META.data[0] = new AGDungeonSoapArrayAssociation();
//response.META.data[0].key
//response.META.data[0].value
response.READ = new AGDungeonSoapArrayAssociation[1][];
response.ERROR = new AGDungeonSoapArrayAssociation[1][];
response = dsoap.Register("PING", parametrs, options);
Console.WriteLine("la taille du tableau data est : " + response.META.data.Length);
Console.ReadLine(); |
dans ce code j'essaye juste de m'assurer que j'ai reçu une réponse (data.length), avant de passer à la sérialisation, mais déjà à ce niveau, j'ai l'erreur :
Citation:
NullReferenceException n'a pas été gérée La référence d'objet n'est pas définie à une instance d'un objet.
exactement à la ligne
Code:
Console.WriteLine("la taille du tableau data est : " + response.META.data.Length);
J'ai l'impression que la réponse de la méthode Register ne "colle" pas avec l'objet "response" que j'ai instancié de type AGDungeonSoapResponse, j'ai essayé comme vous pouvez le constater, d'instancier les objets contenus dans "reponse" à savoir META, READ et ERROR mais sans résultat.
Je ne comprend pas quel est le problème, sachant que le service est fonctionnel et répond correctement via SoapUi.
Quelq'un peut m'aider svp, je reste à disposition si vous voulez plus d'infos.
Cordialement