Como: recuperar metadados e implementar um serviço em conformidade

Muitas vezes, a mesma pessoa não projeta e implementa serviços. Em ambientes onde os aplicativos de interoperação são importantes, os contratos podem ser projetados ou descritos na WSDL e um desenvolvedor deve implementar um serviço que esteja em conformidade com o contrato fornecido. Você também pode querer migrar um serviço existente para o Windows Communication Foundation (WCF), mas preservar o formato de fio. Além disso, os contratos duplex exigem que os chamadores implementem um contrato de retorno de chamada também.

Nesses casos, você deve usar a Ferramenta de Utilitário de Metadados do ServiceModel (Svcutil.exe) (ou uma ferramenta equivalente) para gerar uma interface de contrato de serviço em um idioma gerenciado que você pode implementar para atender aos requisitos do contrato. Normalmente, a Ferramenta de Utilitário de Metadados do ServiceModel (Svcutil.exe) é usada para adquirir um contrato de serviço que é usado com uma fábrica de canais ou um tipo de cliente WCF, bem como com um arquivo de configuração do cliente que configura a associação e o endereço corretos. Para usar o arquivo de configuração gerado, você deve alterá-lo para um arquivo de configuração de serviço. Talvez você também precise modificar o contrato de serviço.

Para recuperar metadados e implementar um serviço em conformidade

  1. Use a Ferramenta de Utilitário de Metadados do ServiceModel (Svcutil.exe) em arquivos de metadados ou em um ponto de extremidade de metadados para gerar um arquivo de código.

  2. Pesquise a parte do arquivo de código de saída que contém a interface de interesse (caso haja mais de uma) marcada com o atributo System.ServiceModel.ServiceContractAttribute. O exemplo de código a seguir mostra as duas interfaces geradas pela Ferramenta de Utilitário de Metadados do ServiceModel (Svcutil.exe). A primeira (ISampleService) é a interface do contrato de serviço que você implementa para criar um serviço em conformidade. O segundo (ISampleServiceChannel) é uma interface auxiliar para uso do cliente que estende a interface do contrato de serviço e System.ServiceModel.IClientChannel e é usada em um aplicativo cliente.

    [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "3.0.0.0")]
    [System.ServiceModel.ServiceContractAttribute(
      Namespace="http://microsoft.wcf.documentation"
    )]
    public interface ISampleService
    {
    
        [System.ServiceModel.OperationContractAttribute(
          Action="http://microsoft.wcf.documentation/ISampleService/SampleMethod",
          ReplyAction="http://microsoft.wcf.documentation/ISampleService/SampleMethodResponse"
        )]
        [System.ServiceModel.FaultContractAttribute(
          typeof(microsoft.wcf.documentation.SampleFault),
          Action="http://microsoft.wcf.documentation/ISampleService/SampleMethodSampleFaultFault"
        )]
        string SampleMethod(string msg);
    }
    
    [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "3.0.0.0")]
    public interface ISampleServiceChannel : ISampleService, System.ServiceModel.IClientChannel
    {
    }
    
  3. Se o WSDL não especificar uma ação de resposta para todas as operações, os contratos de operação gerados poderão ter a propriedade ReplyAction definida como caractere curinga (*). Remova essa configuração de propriedade. Caso contrário, quando você implementa os metadados do contrato de serviço, os metadados não podem ser exportados para essas operações.

  4. Implemente a interface em uma classe e hospede o serviço. Para obter um exemplo, consulte Como implementar um contrato de serviço ou ver uma implementação simples abaixo na seção Exemplo.

  5. No arquivo de configuração do cliente gerado pela Ferramenta de Utilitário de Metadados do ServiceModel (Svcutil.exe), altere a seção de configuração do <cliente> para uma seção de configuração de <serviços>. (Para obter um exemplo de um arquivo de configuração de aplicativo cliente gerado, consulte a seção “Exemplo” a seguir.)

  6. Na seção de configuração de <serviços>, crie um atributo name na seção de configuração de <serviços> para implementação do seu serviço.

  7. Defina o atributo de serviço name como o nome de configuração da implementação do serviço.

  8. Adicione os elementos de configuração do ponto de extremidade que usam o contrato de serviço implementado à seção de configuração de serviço.

Exemplo

O exemplo de código a seguir mostra a maioria de um arquivo de código gerado executando a Ferramenta de Utilitário de Metadados do ServiceModel (Svcutil.exe) em arquivos de metadados.

O código a seguir mostra:

  • A interface do contrato de serviço que, quando implementada, atende aos requisitos do contrato (ISampleService).

  • A interface auxiliar para uso do cliente que estende a interface do contrato de serviço e System.ServiceModel.IClientChannel e é usada em um aplicativo cliente (ISampleServiceChannel).

  • A classe auxiliar que estende System.ServiceModel.ClientBase<TChannel> e é usada em um aplicativo cliente (SampleServiceClient).

  • O arquivo de configuração gerado a partir do serviço.

  • A implementação de serviço ISampleService simples.

  • Uma conversão do arquivo de configuração do lado do cliente em uma versão do lado do serviço.

//------------------------------------------------------------------------------
// <auto-generated>
//     This code was generated by a tool.
//     Runtime Version:2.0.50727.42
//
//     Changes to this file may cause incorrect behavior and will be lost if
//     the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------

[assembly: System.Runtime.Serialization.ContractNamespaceAttribute("http://microsoft.wcf.documentation", ClrNamespace="microsoft.wcf.documentation")]

namespace microsoft.wcf.documentation
{
    using System.Runtime.Serialization;

    [System.CodeDom.Compiler.GeneratedCodeAttribute("System.Runtime.Serialization", "3.0.0.0")]
    [System.Runtime.Serialization.DataContractAttribute()]
    public partial class SampleFault : object, System.Runtime.Serialization.IExtensibleDataObject
    {

        private System.Runtime.Serialization.ExtensionDataObject extensionDataField;

        private string FaultMessageField;

        public System.Runtime.Serialization.ExtensionDataObject ExtensionData
        {
            get
            {
                return this.extensionDataField;
            }
            set
            {
                this.extensionDataField = value;
            }
        }

        [System.Runtime.Serialization.DataMemberAttribute()]
        public string FaultMessage
        {
            get
            {
                return this.FaultMessageField;
            }
            set
            {
                this.FaultMessageField = value;
            }
        }
    }
}

[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "3.0.0.0")]
[System.ServiceModel.ServiceContractAttribute(
  Namespace="http://microsoft.wcf.documentation"
)]
public interface ISampleService
{

    [System.ServiceModel.OperationContractAttribute(
      Action="http://microsoft.wcf.documentation/ISampleService/SampleMethod",
      ReplyAction="http://microsoft.wcf.documentation/ISampleService/SampleMethodResponse"
    )]
    [System.ServiceModel.FaultContractAttribute(
      typeof(microsoft.wcf.documentation.SampleFault),
      Action="http://microsoft.wcf.documentation/ISampleService/SampleMethodSampleFaultFault"
    )]
    string SampleMethod(string msg);
}

[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "3.0.0.0")]
public interface ISampleServiceChannel : ISampleService, System.ServiceModel.IClientChannel
{
}

[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "3.0.0.0")]
public partial class SampleServiceClient : System.ServiceModel.ClientBase<ISampleService>, ISampleService
{

    public SampleServiceClient()
    {
    }

    public SampleServiceClient(string endpointConfigurationName) :
            base(endpointConfigurationName)
    {
    }

    public SampleServiceClient(string endpointConfigurationName, string remoteAddress) :
            base(endpointConfigurationName, remoteAddress)
    {
    }

    public SampleServiceClient(string endpointConfigurationName, System.ServiceModel.EndpointAddress remoteAddress) :
            base(endpointConfigurationName, remoteAddress)
    {
    }

    public SampleServiceClient(System.ServiceModel.Channels.Binding binding, System.ServiceModel.EndpointAddress remoteAddress) :
            base(binding, remoteAddress)
    {
    }

    public string SampleMethod(string msg)
    {
        return base.Channel.SampleMethod(msg);
    }
}
<configuration>
    <system.serviceModel>
        <bindings>
            <basicHttpBinding>
                <binding name="BasicHttpBinding_ISampleService" 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://localhost:8080/SampleService" binding="basicHttpBinding"
                bindingConfiguration="BasicHttpBinding_ISampleService" contract="ISampleService"
                name="BasicHttpBinding_ISampleService" />
        </client>
    </system.serviceModel>
</configuration>
// Implement the service. This is a very simple service.
class SampleService : ISampleService
{
  public string SampleMethod(string msg)
  {
    Console.WriteLine("The caller said: \"{0}\"", msg);
    return "The service greets you: " + msg;
  }
}
<configuration>
  <system.serviceModel>
    <bindings>
      <basicHttpBinding>
        <binding name="BasicHttpBinding_ISampleService" 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>
    <services>
      <service
          name="Microsoft.WCF.Documentation.SampleService">
        <endpoint address="http://localhost:8080/SampleService" binding="basicHttpBinding"
            bindingConfiguration="BasicHttpBinding_ISampleService" contract="Microsoft.WCF.Documentation.ISampleService"
            />
      </service>
    </services>
  </system.serviceModel>
</configuration>

Confira também