2008-09-10 23 views
89

¿Alguien sabe de un buen ejemplo de cómo exponer un servicio WCF programáticamente sin el uso de un archivo de configuración? Sé que el modelo de objeto de servicio ahora es mucho más rico con WCF, así que sé que es posible. Simplemente no he visto un ejemplo de cómo hacerlo. Por el contrario, me gustaría ver cómo se consume también sin un archivo de configuración.WCF Configuración sin un archivo de configuración

Antes de que alguien pregunte, tengo una necesidad muy específica de hacer esto sin los archivos de configuración. Normalmente no recomendaría tal práctica, pero como dije, hay una necesidad muy específica en este caso.

+0

¿Por qué no recomendaría una práctica así (exponiendo el servicio programáticamente sin configuración)? – BornToCode

Respuesta

111

Consumir un servicio web sin un archivo de configuración es muy simple, como he descubierto. Simplemente necesita crear un objeto vinculante y un objeto de dirección y pasarlos al constructor del proxy del cliente o a una instancia genérica de ChannelFactory. Usted puede mirar en el app.config por defecto para ver qué configuración utilizar, a continuación, crear un método de ayuda estática en alguna parte que crea instancias de su proxy:

internal static MyServiceSoapClient CreateWebServiceInstance() { 
    BasicHttpBinding binding = new BasicHttpBinding(); 
    // I think most (or all) of these are defaults--I just copied them from app.config: 
    binding.SendTimeout = TimeSpan.FromMinutes(1); 
    binding.OpenTimeout = TimeSpan.FromMinutes(1); 
    binding.CloseTimeout = TimeSpan.FromMinutes(1); 
    binding.ReceiveTimeout = TimeSpan.FromMinutes(10); 
    binding.AllowCookies = false; 
    binding.BypassProxyOnLocal = false; 
    binding.HostNameComparisonMode = HostNameComparisonMode.StrongWildcard; 
    binding.MessageEncoding = WSMessageEncoding.Text; 
    binding.TextEncoding = System.Text.Encoding.UTF8; 
    binding.TransferMode = TransferMode.Buffered; 
    binding.UseDefaultWebProxy = true; 
    return new MyServiceSoapClient(binding, new EndpointAddress("http://www.mysite.com/MyService.asmx")); 
} 
+0

Personalmente me gusta este enfoque para ejemplos cuando va a utilizar el archivo en un asunto diferente, por ejemplo, si ha encriptado su app.config (o archivo de configuración equivalente) y no necesita usar el built in Capacidades WCF de lectura en una conexión – Noah

+18

Para uso de https, agregue binding.Security.Mode = BasicHttpSecurityMode.Transport; – ciscoheat

+0

Esto funcionó bastante bien para mí. Las únicas diferencias para mí es que también configuré ReaderQuotas y la información de Seguridad. Hice uso de los consejos de ciscoheat y configuré el Security.Transport.Mode para transportarlo usando https (para mí esto no se conoce en tiempo de compilación). –

5

No es fácil en el servidor side ..

Por el lado del cliente, puede utilizar ChannelFactory

3

configuración WCF Todo se puede hacer mediante programación. Por lo tanto, es posible crear servidores y clientes sin un archivo de configuración.

Recomiendo el libro "Programación de servicios WCF" por Juval Lowy, que contiene muchos ejemplos de configuración programática.

2

me encontré con el blog en el siguiente enlace en torno a este tema muy interesante.

Una idea que me gusta es la de poder simplemente pasar una sección de enlace o comportamiento o dirección XML desde la configuración al objeto WCF apropiado y dejar que maneje la asignación de las propiedades; actualmente no se puede hacer.

Al igual que otros en la web, tengo problemas con la necesidad de que mi implementación de WCF use un archivo de configuración diferente al de mi aplicación de alojamiento (que es un servicio .NET 2.0 de Windows).

http://salvoz.com/blog/2007/12/09/programmatically-setting-wcf-configuration/

+0

Este enlace no funciona. – Newbee

+0

Se ha solucionado el enlace roto. – Tone

2

Es muy fácil de hacer en el cliente y el servidor. El libro de Juval Lowy tiene excelentes ejemplos.

En cuanto a su comentario sobre los archivos de configuración, diría que los archivos de configuración son los segundos de un hombre pobre para hacerlo en código. Los archivos de configuración son excelentes cuando controlas a cada cliente que se conectará a tu servidor y te aseguras de que estén actualizados, y que los usuarios no pueden encontrarlos y cambiar nada. Considero que el modelo de archivo de configuración de WCF es limitado, levemente difícil de diseñar y una pesadilla de mantenimiento. Con todo, creo que fue una muy mala decisión de MS hacer que los archivos de configuración sean la forma predeterminada de hacer las cosas.

EDITAR: Una de las cosas que no puede hacer con el archivo de configuración es crear servicios con constructores no predeterminados. Esto conduce a variables estáticas/globales y singletons y otros tipos de sinsentido en WCF.

19

Si está interesado en eliminar el uso de la sección System.ServiceModel en el archivo web.config para IIS hosting, he publicado un ejemplo de cómo hacerlo aquí (http://bejabbers2.blogspot.com/2010/02/wcf-zero-config-in-net-35-part-ii.html). Muestro cómo personalizar un ServiceHost para crear puntos finales de metadata y wshttpbinding. Lo hago de una manera general que no requiere codificación adicional. Para aquellos que no están actualizando de inmediato a.NET 4.0 esto puede ser bastante conveniente.

+0

John, estoy seguro de que es una gran publicación de blog, pero como hay una respuesta aceptada de hace 17 meses, ¿hay realmente algún propósito para su respuesta? –

+36

Dado que esta es mi primera respuesta de desbordamiento de pila que puede no ser la forma en que normalmente se hacen las cosas. Al estar familiarizados con los libros de Lowy y Bustamante, que son excelentes referencias, creo que mi respuesta va más allá de las muestras que ofrecen. Principalmente uso Stack Overflow cuando busco en Google, así que leo publicaciones que son más antiguas con frecuencia. Tener respuestas más actualizadas solo me ayuda desde mi perspectiva. Busqué en Google esta publicación antes de escribir mi código para evitar reinventar la rueda. –

+0

bien, pero cuando lea las preguntas frecuentes (http://stackoverflow.com/faq, enlazadas en cada página), encontrará que este es un sitio de preguntas y respuestas, no un foro de discusión. Ya hubo una gran cantidad de "A" para esta "Q", y hace 17 meses, así que en mi humilde opinión, esto es cuestionable. –

14

Aquí, este es un código completo y funcional. Creo que te ayudará mucho. Estaba buscando y nunca encuentro un código completo, por eso intenté poner un código completo y funcional. Buena suerte.

public class ValidatorClass 
{ 
    WSHttpBinding BindingConfig; 
    EndpointIdentity DNSIdentity; 
    Uri URI; 
    ContractDescription ConfDescription; 

    public ValidatorClass() 
    { 
     // In constructor initializing configuration elements by code 
     BindingConfig = ValidatorClass.ConfigBinding(); 
     DNSIdentity = ValidatorClass.ConfigEndPoint(); 
     URI = ValidatorClass.ConfigURI(); 
     ConfDescription = ValidatorClass.ConfigContractDescription(); 
    } 


    public void MainOperation() 
    { 
     var Address = new EndpointAddress(URI, DNSIdentity); 
     var Client = new EvalServiceClient(BindingConfig, Address); 
     Client.ClientCredentials.ServiceCertificate.Authentication.CertificateValidationMode = X509CertificateValidationMode.PeerTrust; 
     Client.Endpoint.Contract = ConfDescription; 
     Client.ClientCredentials.UserName.UserName = "companyUserName"; 
     Client.ClientCredentials.UserName.Password = "companyPassword"; 
     Client.Open(); 

     string CatchData = Client.CallServiceMethod(); 

     Client.Close(); 
    } 



    public static WSHttpBinding ConfigBinding() 
    { 
     // ----- Programmatic definition of the SomeService Binding ----- 
     var wsHttpBinding = new WSHttpBinding(); 

     wsHttpBinding.Name = "BindingName"; 
     wsHttpBinding.CloseTimeout = TimeSpan.FromMinutes(1); 
     wsHttpBinding.OpenTimeout = TimeSpan.FromMinutes(1); 
     wsHttpBinding.ReceiveTimeout = TimeSpan.FromMinutes(10); 
     wsHttpBinding.SendTimeout = TimeSpan.FromMinutes(1); 
     wsHttpBinding.BypassProxyOnLocal = false; 
     wsHttpBinding.TransactionFlow = false; 
     wsHttpBinding.HostNameComparisonMode = HostNameComparisonMode.StrongWildcard; 
     wsHttpBinding.MaxBufferPoolSize = 524288; 
     wsHttpBinding.MaxReceivedMessageSize = 65536; 
     wsHttpBinding.MessageEncoding = WSMessageEncoding.Text; 
     wsHttpBinding.TextEncoding = Encoding.UTF8; 
     wsHttpBinding.UseDefaultWebProxy = true; 
     wsHttpBinding.AllowCookies = false; 

     wsHttpBinding.ReaderQuotas.MaxDepth = 32; 
     wsHttpBinding.ReaderQuotas.MaxArrayLength = 16384; 
     wsHttpBinding.ReaderQuotas.MaxStringContentLength = 8192; 
     wsHttpBinding.ReaderQuotas.MaxBytesPerRead = 4096; 
     wsHttpBinding.ReaderQuotas.MaxNameTableCharCount = 16384; 

     wsHttpBinding.ReliableSession.Ordered = true; 
     wsHttpBinding.ReliableSession.InactivityTimeout = TimeSpan.FromMinutes(10); 
     wsHttpBinding.ReliableSession.Enabled = false; 

     wsHttpBinding.Security.Mode = SecurityMode.Message; 
     wsHttpBinding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Certificate; 
     wsHttpBinding.Security.Transport.ProxyCredentialType = HttpProxyCredentialType.None; 
     wsHttpBinding.Security.Transport.Realm = ""; 

     wsHttpBinding.Security.Message.NegotiateServiceCredential = true; 
     wsHttpBinding.Security.Message.ClientCredentialType = MessageCredentialType.UserName; 
     wsHttpBinding.Security.Message.AlgorithmSuite = System.ServiceModel.Security.SecurityAlgorithmSuite.Basic256; 
     // ----------- End Programmatic definition of the SomeServiceServiceBinding -------------- 

     return wsHttpBinding; 

    } 

    public static Uri ConfigURI() 
    { 
     // ----- Programmatic definition of the Service URI configuration ----- 
     Uri URI = new Uri("http://localhost:8732/Design_Time_Addresses/TestWcfServiceLibrary/EvalService/"); 

     return URI; 
    } 

    public static EndpointIdentity ConfigEndPoint() 
    { 
     // ----- Programmatic definition of the Service EndPointIdentitiy configuration ----- 
     EndpointIdentity DNSIdentity = EndpointIdentity.CreateDnsIdentity("tempCert"); 

     return DNSIdentity; 
    } 


    public static ContractDescription ConfigContractDescription() 
    { 
     // ----- Programmatic definition of the Service ContractDescription Binding ----- 
     ContractDescription Contract = ContractDescription.GetContract(typeof(IEvalService), typeof(EvalServiceClient)); 

     return Contract; 
    } 
} 
+0

¡Muy buen ejemplo! Usted demuestra casi todos los aspectos de la configuración manual. ¡Bien hecho! – Kilhoffer

+0

+1 para mostrar la configuración del contrato de punto final dinámico – Sal

+3

No entiendo cómo se ajusta EvalServiceClient en este código. Está referenciado, pero no definido. ¿Por qué el servidor está creando un cliente? – BlueMonkMN

Cuestiones relacionadas