Lorsqu'on développe des WebServices, il arrive un moment (très vite) où l'on souhaite renvoyer des objets qu'on a concu soit même (une liste de films ou une liste de livres, ...).
Ainsi on a une classe définissant l'Unité de l'objet (Une ville par exemple), et on va définir une autre classe qui donnera un tableau d'objets.
Ainsi une des fonctions de mon WebService (celle que je montrerai ici) doit renvoyer un tableau de villes.
Les classes sont très simples à faire, et le WebService aussi (cf le code suivant).
------------------------------
Ainsi dans le fichier xxx.ASMX, on va pouvoir ajouter une fonction qui va renvoyer une liste de ville à partir du code du département (cf code joint)
Le code joint fonctionne mais on doit rajouter une option (et c'est la spécificité de l'objet personnel qui est demandé).
En effet, le système ne connait pas le type détaillé de l'objet Ville, ainsi quand il doit renvoyer une liste de Ville (tableau de villes), il aura tendance à créer une erreur comme celle-ci :
------
System.InvalidOperationException: There was an error generating the
XML document. ---> System.InvalidOperationException: The type
Ville was not expected. Use the
XmlInclude or SoapInclude attribute to specify types that are not
known statically.
....
------
Pour éviter ceci, il faut ajouter (dans le fichier xxx.ASMX.VB) une classe dans l'importation : Imports System.Xml.Serialization
et enfin demander dans l'appel de la fonction à ce qu'il récupère d'abord le type Ville avant de travailler. Cela se fait en modifiant ce qui est dans le WebMethod et en conservant tout le reste pareil :
-----
<WebMethod(Description:="Renvoie la liste des villes situées dans le Département fourni"), XmlInclude(GetType(Ville))> Public Function GetAllVillesDepartement(ByVal Departement As Integer) As AllVilles
...
-----
Le "XmlInclude(GetType(Ville))", spécifie au système de commencer par récupérer le type complexe de l'Objet et d'ensuite exécuter la fonction, ainsi qd la fonction lui renverra le Tableau d'objet, il connaîtra déja le type exacte de cet objet.
Source / Exemple :
' Le fichier ville.vb contenant la classe Ville (élément unique) et la classe AllVilles (Liste des villes)
' -----------------------------------------------------
Imports System.Collections.Specialized
<Serializable()> Public Class Ville
Public CodePostal As String = ""
Public NomVille As String = ""
Public Departement As String = ""
' -----------------------------------------------------
Public Sub New()
' Charge Une Ville Vide
End Sub
' -----------------------------------------------------
Public Sub New(ByVal LeNomVille As String)
' Charge Toutes les info sur la Ville ayant le Nom et le district donné
Me.SetVille(LeNomVille, LeCodeDistrict)
End Sub
' -----------------------------------------------------
Public Sub SetVille(ByVal LaVille As String)
' Charge Toutes les info sur la Ville ayant le Nom
Dim sSQL As String = "SELECT ........;" 'Je vous laisse la requette à faire
Dim oConn As SqlClient.SqlConnection
Dim oReader As SqlClient.SqlDataReader
Try
oConn = New System.Data.SqlClient.SqlConnection()
oConn.ConnectionString = Constantes.ChaineConnexionSecurauth
oConn.Open()
Dim oCommand As SqlClient.SqlCommand = New SqlClient.SqlCommand(sSQL, oConn)
oReader = oCommand.ExecuteReader()
While oReader.Read
Me.NomVille = Trim(oReader("NomVille"))
Me.CodePostal = Trim(oReader("CodePostal"))
Me.Departement = Trim(oReader("Departement"))
End While
Finally
If Not oReader Is Nothing Then
oReader.Close()
End If
If Not oConn Is Nothing Then
oConn.Close()
End If
End Try
End Sub
' -----------------------------------------------------
End Class
<Serializable()> Public Class AllVilles
Public ListeVilles As New ArrayList()
' -----------------------------------------------------
Public Sub New()
' Charge Une Liste de Villes Vide
End Sub
' -----------------------------------------------------
Public Sub ChargeListeVilleDepartement(ByVal Departement As Integer)
' Charge la liste des villes situées dans le Département transmis
Dim sSQL As String = "SELECT ...... ;" ' Je vous laisse la requette à faire
Dim oConn As SqlClient.SqlConnection
Dim oReader As SqlClient.SqlDataReader
Try
oConn = New System.Data.SqlClient.SqlConnection()
oConn.ConnectionString = Constantes.ChaineConnexionSecurauth
oConn.Open()
Dim oCommand As SqlClient.SqlCommand = New SqlClient.SqlCommand(sSQL, oConn)
oReader = oCommand.ExecuteReader()
Me.ListeVilles.Clear()
While oReader.Read
Me.ListeVilles.Add(New Ville(oReader("NomVille")))
End While
Finally
If Not oReader Is Nothing Then
oReader.Close()
End If
If Not oConn Is Nothing Then
oConn.Close()
End If
End Try
End Sub
' -----------------------------------------------------
End Class
' -----------------------------------------------------
' Code de la fonction pour le WebService avant modification
Imports System.Web.Services
....
' -------------------------------------------------------------
<WebMethod(Description:="Renvoie la liste des villes situées dans le Département fourni")> Public Function GetAllVillesDepartement(ByVal Departement As Integer) As AllVilles
If Departement > 0 Then
Dim oResultat As New AllVilles()
oResultat.ChargeListeVilleDepartement(Departement)
Return oResultat
End If
End Function
' -----------------------------------------------------
' Code de la fonction pour le WebService après modification
Imports System.Web.Services
Imports System.Xml.Serialization
....
' -------------------------------------------------------------
<WebMethod(Description:="Renvoie la liste des villes situées dans le Département fourni"), XmlInclude(GetType(Ville))> Public Function GetAllVillesDepartement(ByVal Departement As Integer) As AllVilles
If Departement > 0 Then
Dim oResultat As New AllVilles()
oResultat.ChargeListeVilleDepartement(Departement)
Return oResultat
End If
End Function
' -------------------------------------------------------------
Conclusion :
J'espère avoir été assez clair dans cet exemple afin de mieu vous aider dans le perfectionnement de vos WebServices.
Bon coding.
Romelard Fabrice (Alias F___)
Vous n'êtes pas encore membre ?
inscrivez-vous, c'est gratuit et ça prend moins d'une minute !
Les membres obtiennent plus de réponses que les utilisateurs anonymes.
Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.
Le fait d'être membre vous permet d'avoir des options supplémentaires.