Pregunta

¿Alguien conoce un buen ejemplo de cómo exponer un servicio WCF mediante programación sin el uso de un archivo de configuración?Sé que el modelo de objetos de servicio es mucho más rico ahora 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.

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

¿Fue útil?

Solución

Consumir un servicio web sin un archivo de configuración es muy simple, como descubrí.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.Puede consultar el archivo app.config predeterminado para ver qué configuraciones usar y luego crear un método auxiliar estático en algún lugar que cree una instancia 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" ) );
}

Otros consejos

Si está interesado en eliminar el uso de la sección System.ServiceModel en web.config para alojamiento IIS, 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 metadatos y puntos finales de enlace wshttp.Lo hago de forma general y no requiere codificación adicional.Para aquellos que no están actualizando inmediatamente a .NET 4.0, esto puede resultar bastante conveniente.

Aquí, este es el código completo y funcional.Creo que te ayudará mucho.Estuve buscando y nunca encontré 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;
    }
}

No es fácil en el servidor. lado..

Para el lado del cliente, puede utilizar CanalFábrica

Toda la configuración de WCF se puede realizar mediante programación.Por tanto, es posible crear servidores y clientes sin un archivo de configuración.

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

Es muy fácil de hacer tanto en el lado del cliente como en el del 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 el segundo de un pobre en hacerlo en código.Los archivos de configuración son excelentes cuando controlas cada cliente que se conectará a tu servidor y te aseguras de que estén actualizados y que los usuarios no puedan encontrarlos ni cambiar nada.Considero que el modelo del archivo de configuración WCF es limitante, levemente difícil de diseñar y una pesadilla de mantenimiento.Considerándolo todo, creo que fue una muy mala decisión por parte 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 tonterías en WCF.

La publicación del blog en el siguiente enlace sobre este tema me pareció muy interesante.

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

Al igual que otros en la web, tengo problemas con la necesidad de que mi implementación WCF utilice 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/

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top