Pergunta

Alguém conhece um bom exemplo de como expor um serviço WCF programaticamente sem o uso de um arquivo de configuração?Eu sei que o modelo de objeto de serviço é muito mais rico agora com o WCF, então sei que é possível.Só não vi um exemplo de como fazer isso.Por outro lado, gostaria de ver como é feito o consumo sem um arquivo de configuração.

Antes que alguém pergunte, tenho uma necessidade muito específica de fazer isso sem arquivos de configuração.Normalmente eu não recomendaria tal prática, mas como disse, há uma necessidade muito específica neste caso.

Foi útil?

Solução

Consumir um serviço web sem arquivo de configuração é muito simples, como descobri.Você simplesmente precisa criar um objeto de ligação e um objeto de endereço e passá-los para o construtor do proxy do cliente ou para uma instância genérica do ChannelFactory.Você pode consultar o app.config padrão para ver quais configurações usar e, em seguida, criar um método auxiliar estático em algum lugar que instancie seu 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" ) );
}

Outras dicas

Se você estiver interessado em eliminar o uso da seção System.ServiceModel no web.config para hospedagem IIS, postei um exemplo de como fazer isso aqui (http://bejabbers2.blogspot.com/2010/02/wcf-zero-config-in-net-35-part-ii.html).Mostro como personalizar um ServiceHost para criar metadados e endpoints wshttpbinding.Faço isso de uma maneira geral que não requer codificação adicional.Para aqueles que não estão atualizando imediatamente para o .NET 4.0, isso pode ser bastante conveniente.

Aqui, este é um código completo e funcional.Acho que vai te ajudar muito.Eu estava pesquisando e nunca encontrei um código completo, por isso tentei colocar um código completo e funcional.Boa sorte.

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;
    }
}

Não é fácil no servidor lado..

Para o lado do cliente, você pode usar Fábrica de canais

Toda a configuração do WCF pode ser feita programaticamente.Portanto é possível criar servidores e clientes sem um arquivo de configuração.

Recomendo o livro "Programming WCF Services" de Juval Lowy, que contém muitos exemplos de configuração programática.

É muito fácil de fazer tanto no lado do cliente quanto no lado do servidor.O livro de Juval Lowy tem excelentes exemplos.

Quanto ao seu comentário sobre os arquivos de configuração, eu diria que os arquivos de configuração são o segundo pobre em fazê-lo em código.Os arquivos de configuração são ótimos quando você controla cada cliente que se conectará ao seu servidor e garante que eles estejam atualizados e que os usuários não possam encontrá-los e alterar nada.Acho que o modelo do arquivo de configuração do WCF é limitante, um pouco difícil de projetar e um pesadelo de manutenção.Resumindo, acho que foi uma decisão muito ruim da MS tornar os arquivos de configuração a forma padrão de fazer as coisas.

EDITAR:Uma das coisas que você não pode fazer com o arquivo de configuração é criar serviços com construtores não padrão.Isso leva a variáveis ​​estáticas/globais e singletons e outros tipos de bobagens no WCF.

Achei a postagem do blog no link abaixo sobre esse tópico muito interessante.

Uma ideia que gosto é poder simplesmente passar uma seção XML de ligação, comportamento ou endereço da configuração para o objeto WCF apropriado e deixá-lo lidar com a atribuição das propriedades - atualmente você não pode fazer isso.

Como outros na web, estou tendo problemas em precisar que minha implementação do WCF use um arquivo de configuração diferente do meu aplicativo de hospedagem (que é um serviço .NET 2.0 do Windows).

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

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top