Dela via


Så här hämtar du metadata och implementerar en kompatibel tjänst

Ofta utformar och implementerar inte samma person tjänster. I miljöer där samverkande program är viktiga kan kontrakt utformas eller beskrivas i WSDL (Web Services Description Language) och en utvecklare måste implementera en tjänst som uppfyller det angivna kontraktet. Du kanske också vill migrera en befintlig tjänst till Windows Communication Foundation (WCF) men behålla trådformatet. Dessutom kräver duplexkontrakt att den som anropar också implementerar ett återanropskontrakt.

I dessa fall måste du använda verktyget ServiceModel Metadata Utility (Svcutil.exe) (eller ett motsvarande verktyg) för att generera ett tjänstkontraktsgränssnitt på ett hanterat språk som du kan implementera för att uppfylla kraven i kontraktet. Vanligtvis används ServiceModel Metadata Utility Tool (Svcutil.exe) för att hämta ett tjänstkontrakt som används med en kanalfabrik eller en WCF-klienttyp samt med en klientkonfigurationsfil som konfigurerar rätt bindning och adress. Om du vill använda den genererade konfigurationsfilen måste du ändra den till en tjänstkonfigurationsfil. Du kan också behöva ändra tjänstkontraktet.

Hämta data och implementera en kompatibel tjänst

  1. Använd verktyget ServiceModel Metadata Utility (Svcutil.exe) mot metadatafiler eller en metadataslutpunkt för att generera en kodfil.

  2. Sök efter den del av utdatakodfilen som innehåller det intressanta gränssnittet (om det finns fler än en) som har markerats med attributet System.ServiceModel.ServiceContractAttribute. I följande kodexempel visas de två gränssnitt som genereras av ServiceModel Metadata Utility Tool (Svcutil.exe). Den första (ISampleService) är det tjänstkontraktsgränssnitt som du implementerar för att skapa en kompatibel tjänst. Den andra (ISampleServiceChannel) är ett hjälpgränssnitt för klientanvändning som utökar både tjänstkontraktsgränssnittet och System.ServiceModel.IClientChannel och är för användning i ett klientprogram.

    [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. Om WSDL inte anger någon svarsåtgärd för alla åtgärder kan de genererade åtgärdskontrakten ha egenskapen ReplyAction inställd på jokertecknet (*). Ta bort den här egenskapsinställningen. Annars kan metadata inte exporteras för dessa åtgärder när du implementerar metadata för tjänstkontraktet.

  4. Implementera gränssnittet på en klass och vara värd för tjänsten. Ett exempel finns i Så här: Implementera ett tjänstkontrakt, eller se en enkel implementering nedan i avsnittet Exempel.

  5. I klientkonfigurationsfilen som ServiceModel Metadata Utility Tool (Svcutil.exe) genererar, ska du ändra klientkonfigurationsavsnittet <> till ett konfigurationsavsnitt för tjänster <>. (Ett exempel på en konfigurationsfil för ett genererat klientprogram finns i följande "Exempel"-avsnitt.)

  6. I avsnittet <tjänster> konfiguration skapar du ett name-attribut i avsnittet <tjänster> konfiguration för din tjänstimplementering.

  7. Ange attributet tjänst name till konfigurationsnamnet för tjänstimplementeringen.

  8. Lägg till de slutpunktskonfigurationselement som använder det implementerade tjänstkontraktet i avsnittet tjänstkonfiguration.

Exempel

I följande kodexempel visas majoriteten av en kodfil som genereras genom att köra verktyget ServiceModel-metadataverktyg (Svcutil.exe) mot metadatafiler.

Följande kod visar:

  • Tjänstkontraktsgränssnittet som, när det implementeras, uppfyller kontraktskraven (ISampleService).

  • Hjälpgränssnittet för klientanvändning som utökar både tjänstkontraktsgränssnittet och System.ServiceModel.IClientChannel och som ska användas i ett klientprogram (ISampleServiceChannel).

  • Hjälpklassen som utökar System.ServiceModel.ClientBase<TChannel> och som ska användas i ett klientprogram (SampleServiceClient).

  • Konfigurationsfilen som genereras från tjänsten.

  • En enkel ISampleService tjänstimplementering.

  • En konvertering av konfigurationsfilen på klientsidan till en version på tjänstsidan.

//------------------------------------------------------------------------------
// <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: \"{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>

Se även