元資料導出即將 ServiceEndpoint 轉為 MetadataSet,核心由 MetadataExporter 抽象類別定義,具體實作為 WsdlExporter。本文介紹其架構與實戰範例。
定義三個抽象方法:ExportContract、ExportEndpoint、GetGeneratedMetadata。前兩者不直接回傳結果,而是暫存於內部 Context,最後由 GetGeneratedMetadata 取出 MetadataSet。另提供 Errors(導出錯誤/警告)、PolicyVersion(WS-Policy 版本)、State(暫存容器)屬性。
繼承 MetadataExporter,新增 ExportEndpoints 支援一次導出多個端點(對應完整服務的 WSDL)。並提供 GeneratedWsdlDocuments(ServiceDescriptionCollection)、GeneratedXmlSchemas(XmlSchemaSet)唯讀屬性。
WSDL 1.1 五大元素與端點三要素對應:
<Service> / <Port> → 完整 ServiceEndpoint(Address 對應 <Address>)。<Binding> → 端點 繫結。<PortType> → 端點 契約。<Message>、<Types>(XML Schema) → 契約中的訊息與資料型別。
圖 1 WSDL 各元素和終結點三要素之間的匹配關系
using System.Diagnostics;
using System.ServiceModel;
using System.ServiceModel.Description;
using System.Text;
using System.Xml;
namespace Artech.MetadataExporting
{
class Program
{
static void Main(string[] args)
{
ContractDescription contract = ContractDescription.GetContract(typeof(IOrderService));
ServiceEndpoint endpoint1 = new ServiceEndpoint(contract, new WS2007HttpBinding(), new EndpointAddress("https://127.0.0.1/orderservice"));
ServiceEndpoint endpoint2 = new ServiceEndpoint(contract, new NetTcpBinding(), new EndpointAddress("net.tcp://127.0.0.1/orderservice"));
XmlQualifiedName serviceName = new XmlQualifiedName("OrderService", "https://www.artech.com/services/");
WsdlExporter exporter = new WsdlExporter();
exporter.ExportEndpoints(new ServiceEndpoint[] { endpoint1, endpoint2 }, serviceName);
MetadataSet metadata = exporter.GetGeneratedMetadata();
using (XmlWriter writer = new XmlTextWriter("metadata.xml", Encoding.UTF8))
{
metadata.WriteTo(writer);
}
Process.Start("metadata.xml");
}
}
}
執行後 IE 開啟 XML(圖 2),可見 6 個 MetadataSection:XML Schema 方言描述資料契約、訊息結構、CLR 基元型別;WSDL 方言構成完整 WSDL 文件,含 WS2007HttpBinding 與 NetTcpBinding 導出的 Policy 斷言。

圖 2 通過 IE 查看導出的元資料