Instrukcje: pobieranie metadanych i implementowanie zgodnej usługi

Często ta sama osoba nie projektuje ani nie implementuje usług. W środowiskach, w których aplikacje współdziałające są ważne, kontrakty mogą być projektowane lub opisywane w usłudze Web Services Description Language (WSDL), a deweloper musi zaimplementować usługę zgodną z dostarczonym kontraktem. Można również przeprowadzić migrację istniejącej usługi do usługi Windows Communication Foundation (WCF), ale zachować format przewodu. Ponadto kontrakty dwukierunkowe wymagają, aby wywołujący zaimplementowali również kontrakt wywołania zwrotnego.

W takich przypadkach należy użyć narzędzia ServiceModel Metadata Utility Tool (Svcutil.exe) (lub równoważnego narzędzia) do wygenerowania interfejsu 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) jest używane do uzyskania kontraktu usługi, który jest używany 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 Utility 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 interfejs zainteresowania (w przypadku, gdy istnieje więcej niż jeden) oznaczoną System.ServiceModel.ServiceContractAttribute atrybutem . Poniższy przykład kodu przedstawia dwa interfejsy wygenerowane przez narzędzie ServiceModel Metadata Utility Tool (Svcutil.exe). Pierwszy z nich to interfejs kontraktu usługi, który implementuje ISampleService się w celu utworzenia zgodnej usługi. Drugi ( ) jest interfejsem pomocnika dla klienta, który rozszerza zarówno interfejs kontraktu usługi, jak i jest do użytku ISampleServiceChannel System.ServiceModel.IClientChannel 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śli akcji odpowiedzi dla wszystkich operacji, wygenerowane kontrakty operacji mogą mieć właściwość ustawioną na symbol ReplyAction wieloznaczny (*). Usuń to ustawienie właściwości. W przeciwnym razie podczas implementowania metadanych kontraktu usługi nie można wyeksportować metadanych dla tych operacji.

  4. Zaim implementuj interfejs w klasie i hostuj usługę. Aby uzyskać przykład, zobacz Instrukcjami: implementowanie kontraktu usługilub zobacz prostą implementację poniżej w sekcji Przykład.

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

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

  7. Ustaw atrybut name usługi 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 Utility (Svcutil.exe) względem plików metadanych.

Poniższy kod pokazuje:

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

  • Interfejs pomocnika dla klienta, który rozszerza interfejs kontraktu usługi i jest System.ServiceModel.IClientChannel do użytku w aplikacji klienckiej ( ISampleServiceChannel ).

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

  • Plik konfiguracji wygenerowany z 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ż