Instrukcje: pobieranie metadanych i implementowanie zgodnej usługi

Często ta sama osoba nie projektuje i implementuje usług. W środowiskach, w których współdziałanie aplikacji jest ważne, kontrakty mogą być projektowane lub opisane w języku WSDL (Web Services Description Language), a deweloper musi zaimplementować usługę zgodną z podaną umową. Możesz również przeprowadzić migrację istniejącej usługi do programu Windows Communication Foundation (WCF), ale zachować format przewodu. Ponadto kontrakty dwukierunkowe wymagają, aby osoby wywołujące zaimplementowały również kontrakt wywołania zwrotnego.

W takich przypadkach należy użyć narzędzia ServiceModel Metadata Tool (Svcutil.exe) (lub równoważnego narzędzia), aby wygenerować interfejs kontraktu usługi w języku zarządzanym, który można zaimplementować w celu spełnienia wymagań kontraktu. Zazwyczaj narzędzie ServiceModel Metadata Utility Tool (Svcutil.exe) służy do uzyskiwania kontraktu usługi używanego z fabryką kanałów lub typem klienta WCF, a także z plikiem konfiguracji klienta, który konfiguruje prawidłowe powiązanie i adres. Aby użyć wygenerowanego pliku konfiguracji, należy zmienić go na plik konfiguracji usługi. Może być również konieczne zmodyfikowanie kontraktu usługi.

Aby pobrać dane i zaimplementować zgodną usługę

  1. Użyj narzędzia ServiceModel Metadata Tool (Svcutil.exe) względem plików metadanych lub punktu końcowego metadanych, aby wygenerować plik kodu.

  2. Wyszukaj część pliku kodu wyjściowego, która zawiera interesujący interfejs (jeśli istnieje więcej niż jeden) oznaczony atrybutem System.ServiceModel.ServiceContractAttribute . Poniższy przykład kodu przedstawia dwa interfejsy wygenerowane przez narzędzie ServiceModel Metadata Tool (Svcutil.exe). Pierwszy (ISampleService) to interfejs kontraktu usługi, który implementujesz w celu utworzenia zgodnej usługi. Drugi (ISampleServiceChannel) jest interfejsem pomocniczym do użycia przez klienta, który rozszerza zarówno interfejs kontraktu usługi, jak i System.ServiceModel.IClientChannel jest używany w aplikacji klienckiej.

    [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. Jeśli WSDL nie określa akcji odpowiedzi dla wszystkich operacji, wygenerowane kontrakty operacji mogą mieć ReplyAction właściwość ustawioną na symbol wieloznaczny (*). Usuń to ustawienie właściwości. W przeciwnym razie podczas implementowania metadanych kontraktu usługi metadane nie mogą być eksportowane dla tych operacji.

  4. Zaimplementuj interfejs w klasie i hostuj usługę. Przykład można znaleźć w temacie How to: Implement a Service Contract (Instrukcje: implementowanie kontraktu usługi) lub zobacz prostą implementację poniżej w sekcji Przykład.

  5. W pliku konfiguracji klienta wygenerowanym przez narzędzie ServiceModel Metadata Tool (Svcutil.exe) zmień< sekcję konfiguracji klienta> na sekcję< konfiguracji usług.> (Przykład wygenerowanego pliku konfiguracji aplikacji klienckiej można znaleźć w poniższej sekcji "Przykład".

  6. W sekcji konfiguracji usług> utwórz name atrybut w <sekcji konfiguracji usług> dla implementacji usługi.<

  7. Ustaw atrybut usługi name na nazwę konfiguracji implementacji usługi.

  8. Dodaj elementy konfiguracji punktu końcowego, które używają zaimplementowanego kontraktu usługi do sekcji konfiguracji usługi.

Przykład

Poniższy przykład kodu przedstawia większość pliku kodu wygenerowanego przez uruchomienie narzędzia ServiceModel Metadata Tool (Svcutil.exe) względem plików metadanych.

Poniższy kod pokazuje:

  • Interfejs kontraktu usługi, który po wdrożeniu jest zgodny z wymaganiami umowy (ISampleService).

  • Interfejs pomocnika do użycia przez klienta, który rozszerza zarówno interfejs kontraktu usługi, jak i System.ServiceModel.IClientChannel jest używany w aplikacji klienckiej (ISampleServiceChannel).

  • Klasa pomocnika, która rozszerza System.ServiceModel.ClientBase<TChannel> klasę i jest używana w aplikacji klienckiej (SampleServiceClient).

  • Plik konfiguracji wygenerowany na podstawie usługi.

  • Prosta ISampleService implementacja usługi.

  • Konwersja pliku konfiguracji po stronie klienta na wersję po stronie usługi.

//------------------------------------------------------------------------------
// <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>

Zobacz też