c# - configurar - wcf web config example
Consuma un servicio web SOAP sin depender de la aplicaciĆ³n.config (3)
Establecer la configuración de enlace y punto final en el código es una forma, pero hay otra manera de utilizar la DLL del consumidor y dejar que la configuración permanezca en el archivo App.config existente.
El motivo por el que se produce la InvalidOperationException mencionada es porque el archivo DLL no contiene la configuración de configuración. Siempre confía en App.config para proporcionarlo, pero como está utilizando el DLL en otra aplicación de consola, no encuentra la configuración.
Cuando utilizamos el cuadro de diálogo "Agregar referencia de servicio" para agregar el servicio web al componente del cliente y crear una instancia del servicio web, dejamos que Visual Studio maneje la creación del canal de comunicación y cargue la configuración de configuración. Así que, si somos capaces de crear dicho canal explícitamente a nosotros mismos, entonces podemos administrar la configuración de configuración.
Microsoft proporciona clases para este propósito, ConfigurationChannelFactory<TChannel>
Class es uno. Estados de MSDN:
Proporciona la funcionalidad genérica para crear un elemento de configuración de canal para un tipo específico.
El ConfigurationChannelFactory permite la administración central de la configuración del cliente WCF.
Utilice el cuadro de diálogo "Agregar referencia de servicio" para agregar el servicio web al componente del cliente, ya que necesitamos la instancia de la Interfaz del canal de servicio.
Primero cambie el nombre del archivo App.config generado a App.dll.config y en sus propiedades de archivo cambie la propiedad Copy to Output Directory a Copy Always
Cree una clase que tenga un método que devuelva el objeto Channel para acceder al servicio web, como este:
public class ManageService
{
public static T CreateServiceClient<T>(string configName)
{
string _assemblyLocation = Assembly.GetExecutingAssembly().Location;
var PluginConfig = ConfigurationManager.OpenExeConfiguration(_assemblyLocation);
ConfigurationChannelFactory<T> channelFactory = new ConfigurationChannelFactory<T>(configName, PluginConfig, null);
var client = channelFactory.CreateChannel();
return client;
}
}
Como hemos establecido la propiedad Copiar siempre, VS copia la DLL del proyecto y App.dll.config en la carpeta bin . Assembly.GetExecutingAssembly().Location
devuelve la ubicación del ensamblado y ConfigurationManager.OpenExeConfiguration
Abre el archivo de configuración del cliente especificado como un objeto de Configuración.
PluginConfig
contiene el archivo de configuración App.Config Object y ConfigurationChannelFactory<T>
usa para comunicarse con el servicio.
Este método se puede invocar pasando su objeto de interfaz de canal de servicio de la siguiente manera:
Client = ManageService.CreateServiceClient<SampleService.IKeyServiceChannel>("MetadataExchangeTcpBinding_IKeyService");
SampleService
es el espacio de nombres de mi servicio web. Client
tiene la instancia del servicio web.
Si necesita manejar comunicaciones dúplex y devoluciones de llamada, entonces puede consultar ConfigurationDuplexChannelFactory<TChannel>
Class.
Estoy construyendo un componente .NET que llamará a un servicio web externo. Utilicé el cuadro de diálogo "Agregar referencia de servicio" para agregar el servicio web a mi componente, que genera el código necesario para consumir el servicio y agrega la configuración al archivo app.config.
Estoy probando el componente agregando una referencia a su DLL desde una aplicación de consola y llamando al método apropiado que crea una nueva instancia del servicio web: ... = new MyServiceSoapClient()
. Sin embargo, cuando hago esto, obtengo la siguiente excepción:
InvalidOperationException
No se pudo encontrar el elemento de punto final predeterminado que hace referencia al contrato ''MyServicesSoap'' en la sección de configuración del cliente de ServiceModel. Esto podría deberse a que no se encontró ningún archivo de configuración para su aplicación, o porque no se pudo encontrar ningún elemento de punto final que coincida con este contrato en el elemento del cliente.
Esto tiene sentido ya que el app.config no se presenta con la DLL del componente. ¿Cómo puedo llamar al servicio web sin tener que depender de la configuración en la App.Config?
La configuración en <system.ServiceModel>
en el archivo app.config le indicará al componente cómo conectarse al servicio web externo. El xml es simplemente una representación textual de las clases y enumeraciones necesarias para establecer la conexión predeterminada al servicio web.
Por ejemplo, este es el código que se generó para el servicio web que agregué:
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="MyServicesSoap" closeTimeout="00:01:00" openTimeout="00:01:00"
receiveTimeout="00:10:00" sendTimeout="00:01:00" allowCookies="false"
bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"
maxBufferSize="65536" maxBufferPoolSize="524288" maxReceivedMessageSize="65536"
messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered"
useDefaultWebProxy="true">
<readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
maxBytesPerRead="4096" maxNameTableCharCount="16384" />
<security mode="None">
<transport clientCredentialType="None" proxyCredentialType="None"
realm="" />
<message clientCredentialType="UserName" algorithmSuite="Default" />
</security>
</binding>
</basicHttpBinding>
</bindings>
<client>
<endpoint address="http://services.mycompany.com/WebServices/MyServices.asmx"
binding="basicHttpBinding" bindingConfiguration="MyServicesSoap"
contract="MyServices.MyServicesSoap" name="MyServicesSoap" />
</client>
</system.serviceModel>
Esto se puede traducir a un código como ese:
''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)
Por lo general, cuando utiliza el constructor sin parámetros (es decir, el new MyServicesSoapClient()
), se usará la configuración en el archivo app.config. Sin embargo, puede eludir el archivo app.config al establecer explícitamente los valores de binding
y endpoint
en el código y pasar esas instancias al constructor.
Si se trata de un servicio WCF (que suena, a partir de los mensajes de error), entonces, en su mayor parte, necesitará algo es la aplicación.config, porque es la aplicación.config que le dice al resto de WCF que MyServiceSoapClient es un servicio web (con un pequeño cambio en los dos archivos app.config, esto podría convertirse en un servicio de tuberías con nombre, sin volver a compilar el código ...)
Ahora, si realmente quiere hacer esto sin app.config, debe lanzar el MyServiceSoapClient()
generado y escribir el suyo, basado en HttpWebRequest
.