共用方式為


組態和元數據支援

本主題描述如何啟用系結和綁定項的組態和元數據支援。

組態和元數據概觀

本主題討論以下工作,這些工作是開發通道工作清單中的可選項目 1、2 和 4。

  • 啟用綁定元素的配置檔案支援。

  • 啟用系結的組態檔支援。

  • 匯出綁定項的 WSDL 和原則判斷提示。

  • 識別要插入和設定系結或綁定項的 WSDL 和原則判斷提示。

如需建立使用者定義系結和綁定項的相關信息,請參閱分別 建立 User-Defined 系結和 建立 BindingElement

新增組態支援

若要開啟通道的組態檔支援,您必須實作兩個組態區段: System.ServiceModel.Configuration.BindingElementExtensionElement啟用綁定元素的組態支援,以及 System.ServiceModel.Configuration.StandardBindingElementSystem.ServiceModel.Configuration.StandardBindingCollectionElement<TStandardBinding,TBindingConfiguration>啟用繫結的組態支援。

若要這麼做,最簡單的方式是使用 ConfigurationCodeGenerator 範例工具來產生系結和綁定項的組態程序代碼。

擴展繫結元素擴充項目

下列範例程式代碼取自 Transport: UDP 範例。 UdpTransportElement 是一個 BindingElementExtensionElement,它將 UdpTransportBindingElement 公開給配置系統。 使用一些基本覆寫,範例會定義組態區段名稱、綁定項的類型,以及如何建立綁定項。 然後,用戶可以在組態檔中註冊延伸模組區段,如下所示。

<configuration>  
  <system.serviceModel>  
    <extensions>  
      <bindingElementExtensions>  
      <add name="udpTransport" type="Microsoft.ServiceModel.Samples.UdpTransportElement, UdpTransport" />  
      </bindingElementExtensions>  
    </extensions>  
  </system.serviceModel>  
</configuration>  

擴充套件可以從自定義綁定中引用,以使用 UDP 作為傳輸方式。

<configuration>  
  <system.serviceModel>  
    <bindings>  
      <customBinding>  
       <binding configurationName="UdpCustomBinding">  
         <udpTransport/>  
       </binding>  
      </customBinding>  
    </bindings>  
  </system.serviceModel>  
</configuration>  

新增綁定設定

區段 SampleProfileUdpBindingCollectionElement 是將 StandardBindingCollectionElement<TStandardBinding,TBindingConfiguration> 公開給組態系統的SampleProfileUdpBinding。 大部分的實作會委派給衍生自 SampleProfileUdpBindingConfigurationElementStandardBindingElementSampleProfileUdpBindingConfigurationElement具有與SampleProfileUdpBinding屬性相對應的屬性,並且有函數從ConfigurationElement綁定進行映射。 最後,OnApplyConfiguration 方法會在 SampleProfileUdpBinding 類中被覆寫,如下列範例程式代碼所示。

protected override void OnApplyConfiguration(string configurationName)  
{  
            if (binding == null)  
                throw new ArgumentNullException("binding");  
  
            if (binding.GetType() != typeof(SampleProfileUdpBinding))  
            {  
                var expectedType = typeof(SampleProfileUdpBinding).AssemblyQualifiedName;
                var typePassedIn = binding.GetType().AssemblyQualifiedName;
                throw new ArgumentException($"Invalid type for binding. Expected type: {expectedType}. Type passed in: {typePassedIn}.");  
            }  
            SampleProfileUdpBinding udpBinding = (SampleProfileUdpBinding)binding;  
  
            udpBinding.OrderedSession = this.OrderedSession;  
            udpBinding.ReliableSessionEnabled = this.ReliableSessionEnabled;  
            udpBinding.SessionInactivityTimeout = this.SessionInactivityTimeout;  
            if (this.ClientBaseAddress != null)  
                   udpBinding.ClientBaseAddress = ClientBaseAddress;  
}  

若要向組態系統註冊此處理程式,請將下列區段新增至相關的組態檔。

<configuration>  
  <configSections>  
     <sectionGroup name="system.serviceModel">  
         <sectionGroup name="bindings">  
                 <section name="sampleProfileUdpBinding" type="Microsoft.ServiceModel.Samples.SampleProfileUdpBindingCollectionElement, UdpTransport" />  
         </sectionGroup>  
     </sectionGroup>  
  </configSections>  
</configuration>  

然後,您可以從<system.serviceModel>設定區段中參考它。

<configuration>  
  <system.serviceModel>  
    <client>  
      <endpoint configurationName="calculator"  
                address="soap.udp://localhost:8001/"
                bindingConfiguration="CalculatorServer"  
                binding="sampleProfileUdpBinding"
                contract= "Microsoft.ServiceModel.Samples.ICalculatorContract">  
      </endpoint>  
    </client>  
  </system.serviceModel>  
</configuration>  

新增綁定元素的元數據支援

若要將通道整合到元數據系統中,它必須同時支援原則的匯入和匯出。 這可讓 ServiceModel 元數據公用程式工具(Svcutil.exe) 之類的工具產生綁定項的用戶端。

新增 WSDL 支援

系結中的傳輸綁定項負責匯出和匯入元數據中的尋址資訊。 使用SOAP系結時,傳輸綁定項也應該在元數據中匯出正確的傳輸URI。 下列範例程式代碼取自 Transport: UDP 範例。

WSDL 匯出

若要匯出尋址資訊,UdpTransportBindingElement 會實作 System.ServiceModel.Description.IWsdlExportExtension 介面。 方法 IWsdlExportExtension.ExportEndpoint 會將正確的尋址資訊新增至 WSDL 埠。

if (context.WsdlPort != null)  
{  
    AddAddressToWsdlPort(context.WsdlPort, context.Endpoint.Address, encodingBindingElement.MessageVersion.Addressing);  
}  

UdpTransportBindingElement 端點使用 SOAP 系結時,方法的實作 ExportEndpoint 也會匯出傳輸 URI:

WsdlNS.SoapBinding soapBinding = GetSoapBinding(context, exporter);  
if (soapBinding != null)  
{  
    soapBinding.Transport = UdpPolicyStrings.UdpNamespace;  
}  

WSDL 匯入

若要擴充 WSDL 匯入系統來處理匯入位址,請將下列組態新增至 Svcutil.exe 的組態檔,如 Svcutil.exe.config 檔案所示:

<configuration>  
  <system.serviceModel>  
    <client>  
      <metadata>  
        <wsdlImporters>  
          <extension type=" Microsoft.ServiceModel.Samples.UdpBindingElementImporter, UdpTransport" />  
        </wsdlImporters>  
      </metadata>  
    </client>  
  </system.serviceModel>  
</configuration>  

執行 Svcutil.exe時,有兩個選項可用來載入 WSDL 匯入延伸模組 Svcutil.exe:

  1. 請使用 /SvcutilConfig:<file> 將 Svcutil.exe 指向組態檔。

  2. 將組態區段新增至 Svcutil.exe.config,此位置位於與 Svcutil.exe相同的目錄中。

UdpBindingElementImporter 類型實作了 System.ServiceModel.Description.IWsdlImportExtension 介面。 方法 ImportEndpoint 會從 WSDL 埠匯入位址:

BindingElementCollection bindingElements = context.Endpoint.Binding.CreateBindingElements();  
TransportBindingElement transportBindingElement = bindingElements.Find<TransportBindingElement>();  
if (transportBindingElement is UdpTransportBindingElement)  
{  
    ImportAddress(context);  
}  

新增政策支援

自定義綁定項可以在服務端點的 WSDL 系結中匯出原則判斷提示,以表示該綁定項的功能。 下列範例程式代碼取自 Transport: UDP 範例。

原則匯出

UdpTransportBindingElement 型別實作 System.ServiceModel.Description.IPolicyExportExtension 以增加對匯出策略的支援。 因此,System.ServiceModel.Description.MetadataExporter 在任何包含它的系結的政策制定中都包含 UdpTransportBindingElement

IPolicyExportExtension.ExportPolicy 中,新增 UDP 的判斷提示,以及在通道處於多播模式時新增另一個判斷提示。 這是因為多播模式會影響通訊堆疊的建構方式,因此必須在兩端之間協調。

ICollection<XmlElement> bindingAssertions = context.GetBindingAssertions();  
XmlDocument xmlDocument = new XmlDocument();  
bindingAssertions.Add(xmlDocument.CreateElement(  
UdpPolicyStrings.Prefix, UdpPolicyStrings.TransportAssertion, UdpPolicyStrings.UdpNamespace));  
if (Multicast)  
{  
    bindingAssertions.Add(xmlDocument.CreateElement(  
UdpPolicyStrings.Prefix, UdpPolicyStrings.MulticastAssertion,     UdpPolicyStrings.UdpNamespace));  
}  

由於自定義傳輸綁定元素負責處理定址,System.ServiceModel.Description.IPolicyExportExtension 上的 UdpTransportBindingElement 實作也必須處理匯出適當的 WS-Addressing 政策斷言,以指出所使用的 WS-Addressing 版本。

AddWSAddressingAssertion(context, encodingBindingElement.MessageVersion.Addressing);  

政策匯入

若要擴充原則匯入系統,請將下列組態新增至 Svcutil.exe 的組態檔,如 Svcutil.exe.config 檔案所示:

<configuration>  
  <system.serviceModel>  
    <client>  
      <metadata>  
        <policyImporters>  
          <extension type=" Microsoft.ServiceModel.Samples.UdpBindingElementImporter, UdpTransport" />  
        </policyImporters>  
      </metadata>  
    </client>  
  </system.serviceModel>  
</configuration>  

然後,我們實作 System.ServiceModel.Description.IPolicyImportExtension 從已註冊的類別 UdpBindingElementImporter。 在 IPolicyImportExtension.ImportPolicy中,檢查適當命名空間中的判斷提示,並處理用來產生傳輸的判斷提示,並檢查其是否為多播。 此外,請從系結斷言清單中移除匯入程式處理的斷言。 同樣地,執行 Svcutil.exe時,整合有兩個選項:

  1. 使用 /SvcutilConfig:<file> 將 Svcutil.exe 指向我們的配置檔案。

  2. 將組態區段新增至 Svcutil.exe.config,此位置位於與 Svcutil.exe相同的目錄中。

新增自訂標準綁定匯入工具

根據預設,Svcutil.exe 和 System.ServiceModel.Description.WsdlImporter 型別會辨識和匯入系統提供的系結。 否則,系結會匯入為 System.ServiceModel.Channels.CustomBinding 實例。 若要啟用 Svcutil.exe 並讓 WsdlImporter 能匯入 SampleProfileUdpBindingUdpBindingElementImporter 也充當自定義標準系結匯入器。

自訂的標準綁定匯入工具會在 ImportEndpoint 介面上實作 System.ServiceModel.Description.IWsdlImportExtension 方法,以檢查從元數據匯入的 System.ServiceModel.Channels.CustomBinding 實例,以判斷它是否可能由特定標準綁定產生。

if (context.Endpoint.Binding is CustomBinding)  
{  
    Binding binding;  
    if (transportBindingElement is UdpTransportBindingElement)  
    {  
        //if TryCreate is true, the CustomBinding will be replace by a SampleProfileUdpBinding in the  
        //generated config file for better typed generation.  
        if (SampleProfileUdpBinding.TryCreate(bindingElements, out binding))  
        {  
            binding.Name = context.Endpoint.Binding.Name;  
            binding.Namespace = context.Endpoint.Binding.Namespace;  
            context.Endpoint.Binding = binding;  
        }  
    }  
}  

一般而言,實作自定義標準系結匯入工具牽涉到檢查匯入綁定項的屬性,以確認只有標準系結可以設定的屬性已變更,而所有其他屬性都是其預設值。 實作標準系結匯入工具的基本策略是建立標準系結的實例、將系結專案的屬性傳播至標準系結支援的標準系結實例,以及比較標準系結中的綁定項與匯入綁定項。