Procedimiento para recuperar metadatos e implementar un servicio conforme

A menudo, no es el mismo rol quien diseña e implementa los servicios. En entornos donde las aplicaciones que interoperan son importantes, los contratos pueden diseñarse o describirse en lenguaje de descripción de servicios Web (WSDL), y un desarrollador deberá implementar un servicio compatible con el contrato proporcionado. Es posible que quiera migrar un servicio existente a Windows Communication Foundation (WCF), pero conservar el formato de conexión. Además, los contratos dúplex exigen a los autores de llamadas que también implementen un contrato de devolución de llamada.

En estos casos, debe usar la herramienta de utilidad de metadatos de ServiceModel (Svcutil.exe) (o una equivalente) para generar una interfaz de contrato de servicio en un lenguaje administrado que puede implementar para cumplir los requisitos del contrato. Normalmente, la herramienta de utilidad de metadatos de ServiceModel (Svcutil.exe) se usa para adquirir un contrato de servicio que se usa con un generador de canales o un tipo de cliente WCF, así como con un archivo de configuración de cliente que establece el enlace y la dirección correctos. Para utilizar el archivo de configuración generado, debe cambiarlo a un archivo de configuración de servicio. También puede ser necesario modificar el contrato de servicios.

Recuperar datos e implementar un servicio conforme

  1. Use la herramienta de utilidad de metadatos de ServiceModel (Svcutil.exe) contra archivos de metadatos o un punto de conexión de metadatos para generar un archivo de código.

  2. Busque la parte del archivo de código de salida que contiene la interfaz de interés (en caso de que haya más de una) y que se marca con el atributo System.ServiceModel.ServiceContractAttribute. En el siguiente ejemplo de código se muestran las dos interfaces que genera la herramienta de utilidad de metadatos de ServiceModel (Svcutil.exe). La primera (ISampleService) es la interfaz del contrato de servicio que se implementa para crear un servicio conforme. La segunda (ISampleServiceChannel) es una interfaz del asistente, para uso del cliente, que extiende tanto la interfaz del contrato de servicio como System.ServiceModel.IClientChannel, y que se utiliza en una aplicación 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. Si el WSDL no especifica una acción de respuesta para todas las operaciones, los contratos de operación generados pueden tener la propiedad ReplyAction establecida en el carácter comodín (*). Quite este valor de propiedades. De lo contrario, al implementar los metadatos del contrato de servicios, éstos no pueden exportarse para esas operaciones.

  4. Implemente la interfaz en una clase y hospede el servicio. Para ver un ejemplo, consulte Procedimiento para implementar un contrato de servicio, o bien consulte una implementación simple que se muestra a continuación en la sección Ejemplo.

  5. En el archivo de configuración del cliente que genera la herramienta de utilidad de metadatos de ServiceModel (Svcutil.exe), cambie la sección de configuración del <cliente> a una sección de configuración de <servicios>. (Para obtener un ejemplo de un archivo de configuración de la aplicación generado por un cliente, vea la siguiente sección "Ejemplo").

  6. En la sección de configuración de <servicios>, puede crear un atributo name en la sección de configuración de <servicios> para la implementación del servicio.

  7. Establezca el atributo name del servicio en el nombre de configuración para la implementación del servicio.

  8. Agregue los elementos de configuración del punto de conexión que utilizan el contrato de servicios implementado a la sección de configuración de servicio.

Ejemplo

En el siguiente ejemplo de código se muestra la mayor parte de un archivo de código que se genera mediante la ejecución de la herramienta de utilidad de metadatos de ServiceModel (Svcutil.exe) en archivos de metadatos.

El código siguiente muestra:

  • La interfaz del contrato de servicio que, una vez implementada, es conforme a los requisitos de contrato (ISampleService).

  • La interfaz del asistente para uso del cliente que extiende tanto la interfaz de contrato del servicio como System.ServiceModel.IClientChannel, y que se utiliza en una aplicación cliente (ISampleServiceChannel).

  • La clase del asistente que extiende System.ServiceModel.ClientBase<TChannel>, y que se utiliza en una aplicación cliente (SampleServiceClient).

  • El archivo de configuración generado desde el servicio.

  • Una implementación de servicio ISampleService simple.

  • Una conversión del archivo de configuración del cliente en una versión del servicio.

//------------------------------------------------------------------------------
// <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 también