Consuma un servizio web SOAP senza fare affidamento su app.config

Sto creando un componente .NET che chiamerà un servizio web esterno. Ho usato la finestra di dialogo “Aggiungi riferimento servizio” per aggiungere il servizio Web al mio componente, che genera il codice necessario per utilizzare il servizio e aggiunge le impostazioni al file app.config.

Sto testando il componente aggiungendo un riferimento alla sua DLL da un’applicazione console e chiamando il metodo appropriato che crea una nuova istanza del servizio web: ... = new MyServiceSoapClient() . Tuttavia, quando lo faccio, ottengo la seguente eccezione:

InvalidOperationException

Imansible trovare l’elemento endpoint predefinito che fa riferimento al contratto “MyServicesSoap” nella sezione di configurazione del client ServiceModel. Ciò potrebbe essere dovuto al fatto che non è stato trovato alcun file di configurazione per l’applicazione o perché non è stato trovato alcun elemento endpoint che corrisponda a questo contratto nell’elemento client.

Questo ha senso dato che app.config non viene portato con la DLL del componente. Come posso chiamare il servizio Web senza dover fare affidamento sulle impostazioni in App.Config?

Le impostazioni in nel file app.config diranno al componente come connettersi al servizio web esterno. L’xml è semplicemente una rappresentazione testuale delle classi e delle enumerazioni necessarie per effettuare la connessione predefinita al servizio web.

Ad esempio, questo è il codice che è stato generato per il servizio web che ho aggiunto:

                 

Questo può essere tradotto in codice in questo modo:

  '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.MaxStringContentLength = 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) 

In genere, quando si utilizza il costruttore senza parametri (ad es. Il new MyServicesSoapClient() ), verranno utilizzate le impostazioni nel file app.config. Tuttavia, è ansible ignorare il file app.config impostando esplicitamente i valori di bind e endpoint nel codice e passando tali istanze nel costruttore.

L’impostazione della configurazione Binding ed Endpoint nel codice è unidirezionale ma esiste un altro modo di utilizzare la DLL consumer e lasciare che la configurazione rimanga nel file App.config esistente.

Il motivo per cui si verifica l’ InvalidOperationException menzionata è perché la DLL non contiene le impostazioni di configurazione al suo interno. Fa sempre affidamento su App.config per provvedere, ma dal momento che si sta utilizzando la DLL in un’altra applicazione della console, non trova le impostazioni di configurazione.

Quando utilizziamo la finestra di dialogo “Aggiungi riferimento servizio” per aggiungere il servizio Web al componente client e creare un’istanza del servizio Web, permettiamo a Visual Studio di gestire la creazione del canale Comunicazione e caricare le impostazioni di configurazione. Quindi, se siamo in grado di creare un tale canale in modo esplicito, quindi possiamo gestire le impostazioni di configurazione.

Microsoft fornisce Classi per questo scopo, la class ConfigurationChannelFactory è una. MSDN afferma:

Fornisce la funzionalità generica per creare un elemento di configurazione del canale per un tipo specifico.

ConfigurationChannelFactory consente la gestione centralizzata della configurazione del client WCF.

Utilizzare la finestra di dialogo “Aggiungi riferimento servizio” per aggiungere il servizio Web al componente client poiché è necessaria l’istanza di Interfaccia canale di servizio.

Rinominare dapprima il file App.config generato in App.dll.config e nelle proprietà File modificare la proprietà Copia nella directory di output su Copia sempre

Creare una class che abbia un metodo che restituisce l’object Canale per accedere al servizio Web come questo:

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

Poiché abbiamo impostato la proprietà Copia sempre VS copia la DLL di progetto e App.dll.config nella cartella bin . Assembly.GetExecutingAssembly().Location restituisce il percorso dell’assembly e ConfigurationManager.OpenExeConfiguration

Apre il file di configurazione del client specificato come object di configurazione.

PluginConfig contiene il file di configurazione App.Config Object e ConfigurationChannelFactory utilizza per comunicare con il servizio.

Questo metodo può essere chiamato passando l’object interfaccia del canale di servizio in questo modo:

 Client = ManageService.CreateServiceClient("MetadataExchangeTcpBinding_IKeyService"); 

SampleService è lo spazio dei nomi del mio servizio web. Client detiene l’istanza del servizio Web.

Se è necessario gestire la comunicazione duplex e le richiamate, è ansible consultare ConfigurationDuplexChannelFactory Class.

Se questo è un servizio WCF (che sembra, dai messaggi di errore), quindi, per la maggior parte, avrai bisogno di qualcosa è l’app.config, perché è l’app.config che dice al resto di WCF che MyServiceSoapClient è un servizio Web (con una piccola modifica ai due file app.config, questo potrebbe diventare un servizio named pipe, senza ricompilare il codice ….)

Ora, se vuoi davvero farlo senza app.config, devi lanciare il MyServiceSoapClient() generato e scrivere il tuo, basato su HttpWebRequest .