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 duplex-kontrakt anropare att implementera ett återanropskontrakt också.

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 verktyget ServiceModel Metadata Utility (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 är markerad med System.ServiceModel.ServiceContractAttribute attributet. I följande kodexempel visas de två gränssnitt som genereras av ServiceModel Metadata Utility Tool (Svcutil.exe). Det 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 ä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 ReplyAction ha egenskapen 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. Ändra klientkonfigurationsavsnittet till ett< tjänstkonfigurationsavsnitt> i klientkonfigurationsfilen< som verktyget ServiceModel Metadata Utility (Svcutil.exe) genererar.> (Ett exempel på en konfigurationsfil för ett genererat klientprogram finns i följande "Exempel"-avsnitt.)

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

  7. Ange tjänstattributet 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 för ServiceModel-metadata (Svcutil.exe) mot metadatafiler.

Följande kod visar:

  • Gränssnittet för tjänstkontrakt 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 är för användning i ett klientprogram (ISampleServiceChannel).

  • Hjälpklassen som utökar System.ServiceModel.ClientBase<TChannel> och är till för användning 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: \"{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>

Se även