Utiliser un service Web SOAP sans s’appuyer sur app.config

Je construis un composant .NET qui appellera un service Web externe. J’ai utilisé le dialog “Ajouter une référence de service” pour append le service Web à mon composant, ce qui génère le code nécessaire à l’utilisation du service et ajoute les parameters au fichier app.config.

Je teste le composant en ajoutant une référence à sa DLL à partir d’une application console et en appelant la méthode appropriée qui crée une nouvelle instance du service Web: ... = new MyServiceSoapClient() . Cependant, lorsque je le fais, j’obtiens l’exception suivante:

InvalidOperationException

Impossible de trouver l’élément de noeud final par défaut faisant référence au contrat ‘MyServicesSoap’ dans la section de configuration du client ServiceModel. Cela peut être dû au fait qu’aucun fichier de configuration n’a été trouvé pour votre application ou qu’aucun élément de noeud final correspondant à ce contrat n’a été trouvé dans l’élément client.

Cela a du sens puisque le fichier app.config n’est pas transféré avec la DLL du composant. Comment puis-je appeler le service Web sans avoir à compter sur les parameters de App.Config?

Les parameters de dans le fichier app.config indiqueront au composant comment se connecter au service Web externe. Le XML est simplement une représentation textuelle des classes et des énumérations nécessaires pour établir la connexion par défaut au service Web.

Par exemple, il s’agit du code généré pour le service Web que j’ai ajouté:

                 

Cela peut être traduit en code comme suit:

  'Set up the binding element to match the app.config settings ' Dim binding = New BasicHttpBinding() binding.Name = "MyServicesSoap" binding.CloseTimeout = TimeSpan.FromMinutes(1) binding.OpenTimeout = TimeSpan.FromMinutes(1) binding.ReceiveTimeout = TimeSpan.FromMinutes(10) binding.SendTimeout = TimeSpan.FromMinutes(1) binding.AllowCookies = False binding.BypassProxyOnLocal = False binding.HostNameComparisonMode = HostNameComparisonMode.StrongWildcard binding.MaxBufferSize = 65536 binding.MaxBufferPoolSize = 524288 binding.MessageEncoding = WSMessageEncoding.Text binding.TextEncoding = System.Text.Encoding.UTF8 binding.TransferMode = TransferMode.Buffered binding.UseDefaultWebProxy = True binding.ReaderQuotas.MaxDepth = 32 binding.ReaderQuotas.MaxSsortingngContentLength = 8192 binding.ReaderQuotas.MaxArrayLength = 16384 binding.ReaderQuotas.MaxBytesPerRead = 4096 binding.ReaderQuotas.MaxNameTableCharCount = 16384 binding.Security.Mode = BasicHttpSecurityMode.None binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.None binding.Security.Transport.ProxyCredentialType = HttpProxyCredentialType.None binding.Security.Transport.Realm = "" binding.Security.Message.ClientCredentialType = BasicHttpMessageCredentialType.UserName binding.Security.Message.AlgorithmSuite = Security.SecurityAlgorithmSuite.Default 'Define the endpoint address' Dim endpointStr = "http://services.mycompany.com/WebServices/MyServices.asmx" Dim endpoint = New EndpointAddress(endpointStr) 'Instantiate the SOAP client using the binding and endpoint' 'that were defined above' Dim client = New MyServicesSoapClient(binding, endpoint) 

Habituellement, lorsque vous utilisez le constructeur sans paramètre (c’est-à-dire le new MyServicesSoapClient() ), les parameters du fichier app.config sont utilisés. Toutefois, vous pouvez contourner le fichier app.config en définissant explicitement les valeurs de binding et de endpoint dans le code et en transmettant ces instances au constructeur.

Définir la configuration de la liaison et du noeud final dans le code est un moyen, mais il existe un autre moyen d’utiliser la DLL grand public et de laisser la configuration dans le fichier App.config existant.

La cause mentionnée de InvalidOperationException est due au fait que la DLL ne contient pas les parameters de configuration. Il s’appuie toujours sur App.config pour le fournir, mais comme vous utilisez la DLL dans une autre application de la console, il ne trouve pas les parameters de configuration.

Lorsque nous utilisons la boîte de dialog “Ajouter une référence de service” pour append le service Web au composant client et créer une instance du service Web, nous laissons Visual Studio prendre en charge la création du canal de communication et charger le paramètre de configuration. créer ce canal nous-mêmes explicitement, nous pouvons gérer les parameters de configuration.

Microsoft fournit des classes à cette fin, dont ConfigurationChannelFactory . Les états MSDN:

Fournit la fonctionnalité générique pour créer un élément de configuration de canal pour un type spécifique.

ConfigurationChannelFactory permet la gestion centralisée de la configuration du client WCF.

Utilisez la boîte de dialog “Ajouter une référence de service” pour append le service Web au composant client, car nous avons besoin de l’instance Interface de canal de service.

Commencez par renommer le fichier App.config généré en App.dll.config puis, dans ses propriétés de fichier, remplacez la propriété Copier dans le répertoire de sortie par Toujours copier.

Créez une classe qui a une méthode qui renvoie l’object Channel pour accéder au service Web tel que:

 public class ManageService { public static T CreateServiceClient(ssortingng configName) { ssortingng _assemblyLocation = Assembly.GetExecutingAssembly().Location; var PluginConfig = ConfigurationManager.OpenExeConfiguration(_assemblyLocation); ConfigurationChannelFactory channelFactory = new ConfigurationChannelFactory(configName, PluginConfig, null); var client = channelFactory.CreateChannel(); return client; } } 

Depuis que nous avons défini la propriété Copier toujours, VS copie la DLL du projet ainsi que le fichier App.dll.config dans le dossier bin . Assembly.GetExecutingAssembly().Location renvoie l’emplacement de l’assembly et ConfigurationManager.OpenExeConfiguration

Ouvre le fichier de configuration du client spécifié en tant qu’object de configuration.

PluginConfig contient le fichier de configuration App.Config Object et ConfigurationChannelFactory utilise pour communiquer avec le service.

Cette méthode peut être appelée en passant votre object d’interface Service Channel comme suit:

 Client = ManageService.CreateServiceClient("MetadataExchangeTcpBinding_IKeyService"); 

SampleService est l’espace de noms de mon service Web. Client détient l’instance du service Web.

Si vous devez gérer la communication en duplex et les rappels, vous pouvez consulter la classe ConfigurationDuplexChannelFactory .

S’il s’agit d’un service WCF (d’après les messages d’erreur), vous aurez généralement besoin de quelque chose, c’est le fichier app.config, car c’est le fichier app.config qui indique au rest de la WCF que MyServiceSoapClient est un service Web (avec une petite modification apscope aux deux fichiers app.config, cela pourrait devenir un service de canal nommé, sans recomstackr le code ….)

Maintenant, si vous voulez vraiment faire cela sans app.config, alors vous devez jeter le MyServiceSoapClient() généré, et écrire le vôtre, basé sur HttpWebRequest .