Service web et utilisation d'interface
Le
Sébastien
Bonjour,
j'avais d'en l'idée une programmation de ce type là
1 - définition d'une interface
public interface IContrat
{
string libelle{get; set; }
string numero{get; set; }
int prix{get; set; }
int montanttotal{get;}
int Mafonction(int i);
}
2- Classe implémentant l'interface
public class Contrat:IContrat
{}
2 - passer par un service web qui renvoi l'interface
[WebMethod]
public IContrat unefonction()
{
monContrat=new Contrat();
return monContrat
}
quand j'essai de mettre le service web en référence dans un autre projet
voilà l'erreur "Impossible de sérialiser l'interface DemoSW.IContrat. " donc
on ne peut pas mettre l'attribut [Serializable] pour une interface, ensuite
j'ai essayé avec une classe abstraite pareil même erreur, en plus c'est déjà
plus restrictif je trouve l'interface plus intéressante pour son coté
"fonctionnalité minimale garantie" bref impossible de trouver une solution.
Donc première question avez vous une solution ?
deuxième question
je décide de mettre l'interface dans une bibliothèque de classe en me disant
si mon projet Webform a la même bibliothèque en référence peut être qu'alors
ce sera plus facil.
donc j'ai dans le service web un truc du style
private MaBibliothèque.MaClasse monobjet;
[Webmethod]
public MaBibliothèque.MaClasse mafonction()
{
monobjet=new MaBibliothèque.MaClasse();
return monobjet;
}
et dans mon webform un truc genre
public void Button1_click()
{
MaBibliothèque.MaClasse monobjetweb= monserviceweb.mafonction();
}
donc erreur qui dit impossible de convertir monserviceweb.mafonction() en
monobjetweb, ce qui me parait dingue vu que cela est dans la même
bibliothèque de classe le service web et le webform ayant la même classe en
référence.
une idée pour contourner ce problème ?
Merci beaucoup Séb
j'avais d'en l'idée une programmation de ce type là
1 - définition d'une interface
public interface IContrat
{
string libelle{get; set; }
string numero{get; set; }
int prix{get; set; }
int montanttotal{get;}
int Mafonction(int i);
}
2- Classe implémentant l'interface
public class Contrat:IContrat
{}
2 - passer par un service web qui renvoi l'interface
[WebMethod]
public IContrat unefonction()
{
monContrat=new Contrat();
return monContrat
}
quand j'essai de mettre le service web en référence dans un autre projet
voilà l'erreur "Impossible de sérialiser l'interface DemoSW.IContrat. " donc
on ne peut pas mettre l'attribut [Serializable] pour une interface, ensuite
j'ai essayé avec une classe abstraite pareil même erreur, en plus c'est déjà
plus restrictif je trouve l'interface plus intéressante pour son coté
"fonctionnalité minimale garantie" bref impossible de trouver une solution.
Donc première question avez vous une solution ?
deuxième question
je décide de mettre l'interface dans une bibliothèque de classe en me disant
si mon projet Webform a la même bibliothèque en référence peut être qu'alors
ce sera plus facil.
donc j'ai dans le service web un truc du style
private MaBibliothèque.MaClasse monobjet;
[Webmethod]
public MaBibliothèque.MaClasse mafonction()
{
monobjet=new MaBibliothèque.MaClasse();
return monobjet;
}
et dans mon webform un truc genre
public void Button1_click()
{
MaBibliothèque.MaClasse monobjetweb= monserviceweb.mafonction();
}
donc erreur qui dit impossible de convertir monserviceweb.mafonction() en
monobjetweb, ce qui me parait dingue vu que cela est dans la même
bibliothèque de classe le service web et le webform ayant la même classe en
référence.
une idée pour contourner ce problème ?
Merci beaucoup Séb

Poser une question


Donc tu n'a pas à ecrire de fonction pour envoyer une interface.
A moins que tu ais une bonne raison ?
2) Il faut que tout objet envoyé ou retourné par un web service soit
serialisable, et qu'il soit défini dans le WSDL. Donc il doit être defini
dans le web service.
Alexis
en fait l'intérêt d'envoyer une interface était le suivant :
une classe
public class Maclass
public decimal Mafonction()
{
return
((IContrat)monserviceweb.safonctioncalculmontantcontrat()).mapropriétémontan
tdecimal;
}
purement schématique / théorique voir idiot de ma part l'intérêt que j'y
voyais était un couplage faible
par contre je n'ai pas saisi votre (2) en fait quand vous dites "Donc il
doit être défini dans le web service." si je fais une bibliothèque de classe
exemple :
public interface IContrat //ceci n'est pas sérialisable
{
}
public abstract class AContrat:IContrat //je penses qu'une classe abstraite
n'est pas sérialisable en tout cas je suis resté bloqué à moins que cela
viennent du fait qu'elle implémente l'interface IContrat comme une interface
n'est pas sérialisable ce qui implément une interface ne l'est peut être pas
non plus
{
}
public class Contrat:AContrat //je n'ai pas tenté de sérialiser ça mais ça
doit marcher une class est sérialisable sauf si un de ses membres / champs
ne l'est pas
{
}
En fait j'utilises en retour de fonction des interfaces pour faire style
"factory design" ou "adapter design" en ce sens que le retour par interface
me dit "voilà comme c'est l'interface IContrat qui revient on peut lui
demander son montant
Sébastien
"Alexis KARTMANN" news:
Toutes vos remarques sont pertinentes dans une domaine purement
programmation objet mais les WebService n'ont pas cette approche. Le
protocole SOAP utilisé par les WebServices ne gère pas la notion de
hiérarchie de class.
Le découplage entre le client et le serveur est automatiquement fait par la
notion de manifeste qui est contenu dans le fichier de définition du
WebService.
Un client d'un WebService doit être capable de générer une classe de
l'interface du WebService sans avoir le moindre bout de code de la classe
sur le serveur.
Quand vous faite un "Add Web Reference", VS.NET génère une classe proxy pour
l'interface du WebService mais aussi tout le code de
sérialisation/désérialisation des objet passés par valeur lors des appels de
fonctions (pas vraiment des méthodes puisque les objets WebService sont très
majoritairement sans état). Le caractère sérialisable des paramètres permet
à VS.NET d'indiquer au programmeur qu'il doit faire passer des éléments
sérialisable uniquement en XML.
Regardez l'article suivant (particulièrement la 7ème Question/Réponse):
http://msdn.microsoft.com/msdnmag/i...fault.aspx
--
Paul Bacelar
"Sébastien" news:
((IContrat)monserviceweb.safonctioncalculmontantcontrat()).mapropriétémontan
classe
abstraite
interface
pas
interface
WSDL.
defini
m'accorder un peu de temps pour m'éclaircir un point
Voici le coté obscur :
je défini une bibliothèque de classe
namespace MaBibliotheque
{
public class MaClasse {public string nom;...}
}
je fais référence (par add refernce) à cette bibliothèque dans un webservice
donc je dis un truc style
[WebMethod]
public MaBibliotheque.MaClasse UneFonctionSW(MaBibliotheque.MaClasse
unObjet)
{ unObjet.nom="toto";
return unObjet;}
donc ici pas question de hiérarchie, juste de dire que j'utilise un type
issue d'une bibliotheque en retour d'une fonction cela me paraît "standard".
ensuite une classe utilise le webservice et fait référence à la même
Bibliotheque
public class UneClasse
{
public MaBibliotheque.MaClasse unobj=new MaBibliotheque.MaClasse();
public MaBibliotheque.MaClasse unobjbis=new MaBibliotheque.MaClasse();
void Main(...)
{
LeWebService.service1 unobjws=new LeWebService.service1();
unobjbis.nom="TATA";
unobj=unobjws.UneFonctionSW(unobjbis); //ici plantage en disant
"LeWebService.MaClasse ne peut pas être converti en MaBibliotheque.MaClasse"
//si on fait
unobj=(MaBibliotheque.MaClasse)unobjws.UneFonctionSW(unobjbis); //idem
plantage
}
}
Là il y a un truc obscur pour moi il travaille sur la même bibliothèque de
classe mais on ne peut pas caster et il ne se reconnaisse pas entre eux. Je
penses que même avec la question 7 de vbotre exemple le problème ne serait
pas résolu, ou alors il y a quelque chose que je ne saisi pas
Cordialement Sébastien
"Paul Bacelar" de news:
la
pour
de
très
permet
((IContrat)monserviceweb.safonctioncalculmontantcontrat()).mapropriétémontan
ça
champs
de
objets des WebServices.
Si vous les lisez tous attentivement, vous vous rendrez compte que .NET ne
fait que donner un habillage objet à un protocole qui ne l'est pas (SOAP).
Vous avez toujours vos réflexes de programmeurs POO car vous ne voyez que la
surface objet offert par .NET.
Avec l'article, vous devriez commencez à avoir un aperçu de ce qui se cache
sous le capot de .NET.
Prenons votre "Paradoxe" pour illustrer les choses.
Vous pensez que c'est un objet "MaBibliotheque.MaClasse" qui est passé par
le réseau, mais c'est très loin d'être le cas.
SOAP permet de dialoguer entre des machines totalement différentes
BigEndian donc pas, par défaut, une instance sérialisé de MaClasse, qui ne serait
désérialisable que par le même type de machine ou de FrameWork, qui passe
dans le paquet SOAP/HTTP. Pensez aux clients WebService écrit en JAVA avec
AXIM et utilisant le WSDL de .NET pour créer les classes proxy et les
classes correspondants aux objets sérialisables qui passent du WebService au
client et vis vers ça.
Avec cette problématique à l'esprit, vous vous rendez compte que les choses
envoyées sur le réseau ne correspondent pas à une simple sérialisation.
Votre signature de méthode sera interprétée par ASP.NET pour qu'il génère un
WSDL spécifiant le format XML des objets passés et reçus qui correspondra
plus ou moins à votre classe.
Le problème, c'est qu'avec votre vue Objet et pas WebService de votre
méthode, vous ne vous rendez pas compte des compromis fait pour permettre à
un protocole non objet et multi plateforme d'apparaître comme aussi simple
que de l'objet.
Il faut bien comprendre que, sur le réseau, c'est une représentation
standardisée et portable (multi framework) qui circule.
Regardons de plus près ces "imprécisions" fait par ASP.NET.
Premièrement, ce n'est pas un objet qui passe mais du texte au format XML.
ASP.NET délègue au sérialisateur XML la responsabilité de transformer votre
objet en un ensemble d'élément XML. Vous devez donc bien comprendre comment
fonctionne ce sérialisateur pour saisir comment votre type d'objet
"MaClasse" est déclaré dans le WSDL et par la même connaître les champs
(membres) que le sérialisateur XML rend public aux clients du WebService.
Il y a bien une énorme frontière entre votre objet et ce qui passe sur les
fils du réseau. Par exemple, si votre classe ne contient aucune propriété ou
membre public, alors votre objet déclaré dans le WSDL sera vide (sans aucun
membre) car il n'y aura aucune donné à passer. Les membres protected ou
private ne sont utilisés que par le code de votre classe et comme les
méthodes de votre classe ne sont pas transposables vers le client (rappel
que de l'autre coté, coté client, il y a des choses comme une JVM JAVA ou
encore pire ;-) ), ils sont donc complètement escamotés dans le WSDL.
Vous devez donc commencer à comprendre que ce qui passe n'est que de l'XML
généré par le sérialisateur XML. Regardez l'ensemble des attributs du
FrameWork commençants par Xml, vous verrez comment piloter le sérialiseur
XML, quand il utilise la réflexion, pour adapter le WSDL à vos besoins. N'
espérez pas trop de ce pilotage ;-).
Vous avez donc un objet dans votre FrameWork .NET et un contrat dans le WSDL
qui spécifie le format XML des données qui sont échangées. Les données
échangées sont bien plus proches des structures inertes que des objets ayant
un comportement dynamique.
Maintenant, quand vous faite un "Add Web Reference" (Attention au Web ;-) ),
vous utilisez (VS.NET génèrent) des classes qui n'ont comme point commun,
avec votre classe de départ du WebService, que leur respect du contrat
spécifié dans le WSDL. Pensez que c'est peut-être un serveur WebMéthode de
BEA qui fournit le WebService.
Les Classes auto-générées par VS au moment de l'ajout de la WebReference n'
est conforme qu'au contrat dans le WSDL. Si vous n'avez pas des membres
publics dans votre classe MaBibliotheque.MaClasse, la classe
LeWebService.MaClasse n'aura aucun membres, ni public ni privées.
MaBibliotheque.MaClasse"
Maintenant, cette invective de VisualStudio doit vous paraître bien moins
obscure ;-), du moins je l'espère. Il n'y a aucun lien d'héritage ou autre
entre ces 2 classes. Le seul lien est la conformance au WSDL du WbService.
C'est absurde comme instruction. Mais pour le voir il faut commencer à avoir
un certain recul ;-) (Je le répète mais l'article précédemment cité permet d
'avoir ce recul).
Il faut absolument que vous compreniez comment marche me sérialisateur XML
pour vous permettre d'avoir des classes générées par VS.NET plus
utilisables.
En espérant que cela suffise ;-)))
--
Paul Bacelar
"Sébastien" news:
webservice
"standard".
MaBibliotheque.MaClasse"
Je
classe
appels
((IContrat)monserviceweb.safonctioncalculmontantcontrat()).mapropriétémontan
j'y
il
cela
être
mais
style
message