HOW TO:擷取中繼資料並實作相容性服務

服務通常不會由同一個人設計並實作。 在重視應用程式之間互通性的環境中,可以使用 Web 服務描述語言 (WSDL) 來設計或描述合約,而開發人員則必須實作符合所提供合約的服務。 您可能也會想要將現有的服務遷移至 Windows Communication Foundation (WCF),但保留電傳格式。 此外,雙工合約還會要求呼叫端也必須實作回呼合約。

在這些情況下,您必須使用System.servicemodel 中繼資料公用程式工具(Svcutil) (或對等工具),以您可以執行以滿足合約需求的 managed 語言來產生服務合約介面。 通常會使用System.servicemodel 中繼資料公用程式工具(Svcutil)來取得與通道處理站或 WCF 用戶端類型,以及設定正確系結和位址的用戶端設定檔所搭配使用的服務合約。 若要使用產生的組態檔,您必須將它變更為服務組態檔。 您可能還需要修改服務合約。

若要擷取資料並實作相容服務

  1. 對中繼資料檔案或中繼資料端點使用System.servicemodel 中繼資料公用程式工具(Svcutil) ,以產生程式碼檔案。

  2. 搜尋輸出程式碼檔案中包含標示有 System.ServiceModel.ServiceContractAttribute 屬性之所需介面 (如果有一個以上) 的部分。 下列程式碼範例顯示System.servicemodel 中繼資料公用程式工具(Svcutil)所產生的兩個介面。 第一個 (ISampleService) 是您為了建立相容服務而實作的服務合約介面。 第二個 (ISampleServiceChannel) 是供用戶端使用的 Helper 介面,這個介面會擴充服務合約介面及 System.ServiceModel.IClientChannel,而且可以在用戶端應用程式中使用。

    [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. 如果 WSDL 沒有為所有的作業指定回覆動作,則產生的作業合約可能會將 ReplyAction 屬性設定為萬用字元 (*)。 請移除這個屬性設定。 否則,當您實作服務合約中繼資料時,就無法匯出這些作業的中繼資料。

  4. 在類別上實作介面並裝載服務。 如需範例,請參閱範例一節中的如何:執行服務合約或查看下列簡單的執行方式。

  5. 在 [配置中繼資料公用程式工具(Svcutil) ] 產生的用戶端設定檔中,將 [設定] 區段變更為 [設定] <client> <services> 區段。 (如需所產生之用戶端應用程式組態檔的範例,請參閱下列<範例>一節)。

  6. 在 [設定] <services> 區段內,于 name 服務執行的 [設定] 區段中建立屬性 <services>

  7. 將服務的 name 屬性設定為服務實作的組態名稱。

  8. 將使用實作服務合約的端點組態項目加入至服務組態區段。

範例

下列程式碼範例顯示透過對中繼資料檔案執行System.servicemodel 中繼資料公用程式工具(Svcutil)所產生的大部分程式碼檔案。

下列程式碼顯示:

  • 服務合約介面,這個介面會在實作之後符合合約需求 (ISampleService)。

  • 供用戶端使用的 Helper 介面,這個介面會擴充服務合約介面及 System.ServiceModel.IClientChannel,而且可以在用戶端應用程式中 (ISampleServiceChannel) 使用。

  • Helper 類別,這個類別會擴充 System.ServiceModel.ClientBase<TChannel>,而且可以在用戶端應用程式 (SampleServiceClient) 中使用。

  • 從服務產生的組態檔。

  • 簡易 ISampleService 服務實作。

  • 用戶端組態檔轉換為服務端版。

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

請參閱