本主題描述如何啟用系結和綁定項的組態和元數據支援。
組態和元數據概觀
本主題討論以下工作,這些工作是開發通道工作清單中的可選項目 1、2 和 4。
啟用綁定元素的配置檔案支援。
啟用系結的組態檔支援。
匯出綁定項的 WSDL 和原則判斷提示。
識別要插入和設定系結或綁定項的 WSDL 和原則判斷提示。
如需建立使用者定義系結和綁定項的相關信息,請參閱分別 建立 User-Defined 系結和 建立 BindingElement。
新增組態支援
若要開啟通道的組態檔支援,您必須實作兩個組態區段: System.ServiceModel.Configuration.BindingElementExtensionElement啟用綁定元素的組態支援,以及 System.ServiceModel.Configuration.StandardBindingElement和 System.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。 大部分的實作會委派給衍生自 SampleProfileUdpBindingConfigurationElement 的 StandardBindingElement。
SampleProfileUdpBindingConfigurationElement具有與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:
請使用 /SvcutilConfig:<file> 將 Svcutil.exe 指向組態檔。
將組態區段新增至 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時,整合有兩個選項:
使用 /SvcutilConfig:<file> 將 Svcutil.exe 指向我們的配置檔案。
將組態區段新增至 Svcutil.exe.config,此位置位於與 Svcutil.exe相同的目錄中。
新增自訂標準綁定匯入工具
根據預設,Svcutil.exe 和 System.ServiceModel.Description.WsdlImporter 型別會辨識和匯入系統提供的系結。 否則,系結會匯入為 System.ServiceModel.Channels.CustomBinding 實例。 若要啟用 Svcutil.exe 並讓 WsdlImporter 能匯入 SampleProfileUdpBinding,UdpBindingElementImporter 也充當自定義標準系結匯入器。
自訂的標準綁定匯入工具會在 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;
}
}
}
一般而言,實作自定義標準系結匯入工具牽涉到檢查匯入綁定項的屬性,以確認只有標準系結可以設定的屬性已變更,而所有其他屬性都是其預設值。 實作標準系結匯入工具的基本策略是建立標準系結的實例、將系結專案的屬性傳播至標準系結支援的標準系結實例,以及比較標準系結中的綁定項與匯入綁定項。