Como: Recuperar metadados e implementar um serviço compatível

Muitas vezes, a mesma pessoa não projeta e implementa serviços. Em ambientes onde os aplicativos interoperacionais são importantes, os contratos podem ser projetados ou descritos em WSDL (Web Services Description Language) 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 também implementem um contrato de retorno de chamada.

Nesses casos, você deve usar a ServiceModel Metadata Utility Tool (Svcutil.exe) (ou uma ferramenta equivalente) para gerar uma interface de contrato de serviço em uma linguagem gerenciada que você pode implementar para cumprir os requisitos do contrato. Normalmente, a ServiceModel Metadata Utility Tool (Svcutil.exe) é usada para adquirir um contrato de serviço que é usado com uma fábrica de canal ou um tipo de cliente WCF, bem como com um arquivo de configuração de cliente que define a ligação e o endereço corretos. Para usar o arquivo de configuração gerado, você deve alterá-lo em um arquivo de configuração de serviço. Poderá também ter de modificar o contrato de prestação de serviços.

Para recuperar dados e implementar um serviço compatível

  1. Use a ServiceModel Metadata Utility Tool (Svcutil.exe) em arquivos de metadados ou um ponto de extremidade de metadados para gerar um arquivo de código.

  2. Procure a parte do arquivo de código de saída que contém a interface de interesse (no caso de haver mais de um) que está marcada com o System.ServiceModel.ServiceContractAttribute atributo. O exemplo de código a seguir mostra as duas interfaces geradas pelo ServiceModel Metadata Utility Tool (Svcutil.exe). O primeiro (ISampleService) é a interface do contrato de serviço que você implementa para criar um serviço compatível. O segundo (ISampleServiceChannel) é uma interface auxiliar para uso do cliente que estende a interface do contrato de serviço e System.ServiceModel.IClientChannel é para uso 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 podem ter a propriedade definida como o caractere curinga ReplyAction (*). 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 veja uma implementação simples abaixo na seção Exemplo.

  5. No arquivo de configuração do cliente gerado pela ServiceModel Metadata Utility Tool (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 name atributo na seção de configuração de< serviços> para sua implementação de serviço.

  7. Defina o atributo de serviço name como o nome de configuração para sua implementação de 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 pela execução da ferramenta ServiceModel Metadata Utility Tool (Svcutil.exe) em arquivos de metadados.

O código a seguir mostra:

  • A interface do contrato de serviços que, quando implementada, cumpre os requisitos do contrato (ISampleService).

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

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

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

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

  • Uma conversão do arquivo de configuração do lado do cliente para 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>

Consulte também