2010-02-27 4 views
3

Je dois appeler un service Web à partir d'un programme C#. Le webservice n'a probablement pas un format standard. La description de l'interface (wsdl et xsd) est très compliquée, et l'utilisation d'un mécanisme de génération de proxy génère des centaines de classes. Les classes générées sont d'une petite aide car elles sont très génériques, ayant pour la plupart des types d'objets simples comme membres. La meilleure option est de construire le message SOAP manuellement. C'est aussi la manière dont le fournisseur de services Web a suggéré de choisir: Prenez les messages soap/xml qui doivent être envoyés et construisez le message en fonction du modèle. Maintenant, la question est de savoir comment construire le message le plus efficacement possible. Bien sûr, coder en dur la chaîne de message est une option, mais je me demande si de meilleures options existent. Si j'ai le message complet dans une chaîne, comment envoyer au mieux les messages. Dois-je utiliser un simple HttpRequest ou puis-je utiliser les mécanismes de la pile wcf? Mon approche actuelle pour construire le message ressemble à ceci:Appel d'un service Web sans proxy

string msg = envelopeBegin; 
RouteType rootType = new RouteType(); 
XmlSerializer serializer = new XmlSerializer(typeof(RouteType)); 
StringWriter stringWriter = new StringWriter(); 
serializer.Serialize(stringWriter, rootType , customNamespace); 
msg += stringWriter.ToString(); 
msg += envelopeEnd; 

// Envoyer le message sur le fil

Le message Savon/xml Je dois générer ressemble à ceci

<env:Envelope>xmlns:env=http://schemas.xmlsoap.org/soap/envelope/ xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:ns0="http://www.skanska.se/oagis/9/ws/faults"> 
<env:Body> 
<ska:ShowSalesOrder xmlns:ska="http://www.skanska.se/oagis/9" systemEnvironmentCode="UTV" versionID="1.0" releaseID="9.0"> 
<!--plsql=.74s--> 
<ApplicationArea xmlns="http://www.openapplications.org/oagis/9"> 
<!--user_name=SEBA_RAPPE--> 
<ska:Sender> 
<LogicalID>OEBS_SE</LogicalID> 
<ComponentID>SKAIS017I</ComponentID> 
<AuthorizationID>SEBA_RAPPE</AuthorizationID> 
<ska:ResponsibilityID>XXOM_INTEGRATION_SVT</ska:ResponsibilityID> 
</ska:Sender> 
<CreationDateTime>2010-02-26T15:03:27+01:00</CreationDateTime> 
<BODID>xxxxxxxxxxxxxxxxx</BODID> 
</ApplicationArea> 
<ska:DataArea> 
<Show xmlns="http://www.openapplications.org/oagis/9"> 
<ResponseCriteria> 
<ResponseExpression actionCode="Never" expressionLanguage="xPath">*</ResponseExpression> 
</ResponseCriteria> 
</Show> 
<ska:SalesOrder> 
<SalesOrderHeader xmlns="http://www.openapplications.org/oagis/9"> 
<DocumentID> 
<ID>141779</ID> 
</DocumentID> 
<RequestedShipDateTime>2009-11-04T07:00:54+01:00</RequestedShipDateTime> 
</SalesOrderHeader> 
</ska:SalesOrder> 
</ska:DataArea> 
</ska:ShowSalesOrder> 
</env:Body> 
</env:Envelope> 

Répondre

0

Une façon de le faire est de créer un modèle de squelette XML contenant des espaces réservés pour les valeurs. Lisez le XML et remplacez les valeurs par celles de votre objet. Publiez le code XML résultant sur le service Web à l'aide de HttpWebRequest.

Même si cette approche fonctionne, je vous recommande fortement de créer une classe proxy WCF et de l'utiliser à la place même si le service Web contient des centaines de méthodes et d'objets qui ne sont pas utilisés. Tant que c'est un WSDL valide, WCF va le gérer. En outre, s'il y a des changements au service Web, tout ce que vous avez à faire est de régénérer le proxy. Pour éviter la laideur de ce service web, créez votre propre infrastructure qui n'expose que les méthodes et les classes utiles et cache l'appel réel.

2

Vous pouvez certainement encore utiliser l'infrastructure WCF sans avoir besoin de définitions de type pour tous les différents messages. WCF prend spécifiquement en charge cela à travers la classe Message. L'utiliser n'est pas si difficile. Voici quelques informations supplémentaires à leur sujet, mais l'idée est que vous utiliseriez des lecteurs et des écrivains XML pour lire et écrire des messages.

Using the Message Class

+0

oui, cela pourrait être vrai - vous pouvez utiliser des instances de classe typées Message - mais vous ne pouvez pas appeler un service WCF SOAP sans passer par la pile de proxy côté client WCF .... –

+0

Ouais c'est l'idée. Il pourrait encore tirer parti des canaux et de l'infrastructure côté client WCF, mais sans l'explosion des définitions de type côté client. Cela peut être pénible quand vous n'avez besoin que d'une dizaine de types et que le WSDL en définit des centaines. – Josh

+0

@marc_s: Vous pouvez utiliser un socket TCP brut pour accéder à un service WCF si vous le souhaitez, mais il y aurait beaucoup de plomberie à faire, HttpWebRequest serait plus facile. Que voulez-vous dire par "pile proxy côté client WCF"? Il est simple de créer un proxy personnalisé dérivé de System.ServiceModel.ClientBase sans recourir à des proxies verbeux créés par VS.Net. – sipwiz

Questions connexes