首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> 關於.NET

WCF 分散式開發實戰(三):服務中繼資料交換、配置與程式設計完整指南

     編輯:關於.NET

繼前兩篇文章奠定 WCF 分散式開發的基礎觀念與自訂宿主托管實作後,本文將深入探討 WCF 服務中繼資料交換的核心機制。我們將詳細剖析什麼是 WCF 服務中繼資料、為何必須暴露中繼資料交換端點、它與傳統 Web Service 的關聯,以及透過組態檔與程式碼兩種方式實現 HTTP-GET 與 MEX 端點交換的完整流程,助您掌握跨平台、跨語言服務互通的關鍵技術。

一、WCF 服務中繼資料核心觀念

1.1 什麼是 WCF 服務中繼資料?

WCF 服務中繼資料是服務核心三要素——位址、繫結、契約的原始描述資訊。公開的中繼資料主要包含三類 XML 文件:

  • XSD 結構描述:定義資料元素、屬性、資料型別、命名空間等結構規範,支援豐富的資料型別與可擴充模型。
  • WSDL 服務描述:描述服務方法、參數、回傳值、排序等呼叫介面資訊。
  • .Disco 探索文件:記錄服務通訊協定、位址、命名空間等發現資訊。

這些全部基於 XML 標準,確保跨語言、跨平台互通性,這正是 WCF 追求異構系統整合的基石。

1.2 為何必須暴露中繼資料?

用戶端需透過中繼資料了解服務特徵以建立通訊。傳統 Web Service 以自描述、跨平台著稱,WCF 繼承此特性:用戶端根據服務中繼資料反序列化產生本地 Proxy 程式碼(C#、VB、Java 皆可),透過服務代理進行呼叫。暴露中繼資料端點,正是解決異構用戶端與服務互通的關鍵環節。

1.3 WCF 與傳統 Web Service 的對比

WCF 完整支援 Web Service 核心協定。從服務端程式碼結構(.svc 對應 .asmx)、用戶端引用生成的本地檔案(WSDL、XSD、Proxy 類別)來看,兩者高度相似。WCF 框架在參考 ASP.NET Web Service 架構基礎上進行了全方位擴充,提供更靈活的託管、繫結與安全機制。

服務端程式碼結構對比

Web Service 用戶端引用結構

WCF 用戶端引用結構

二、WCF 中繼資料交換兩大方式

WCF 提供兩種發佈中繼資料的標準方式:

  1. HTTP-GET 方式:用戶端透過 HTTP GET 請求直接取得 WSDL/XSD。
  2. MEX 端點交換:使用專用的 IMetadataExchange 契約,支援 HTTP、HTTPS、TCP、Named Pipe 等多種傳輸繫結(mexHttpBinding、mexHttpsBinding、mexTcpBinding、mexNamedPipeBinding)。

對應的列舉 MetadataExchangeClientMode 定義於 System.ServiceModel.Description 命名空間:

public enum MetadataExchangeClientMode
{
    MetadataExchange = 0, // WS-Transfer Get (MEX)
    HttpGet = 1           // HTTP GET
}

啟用中繼資料交換後,必須顯式配置 ServiceMetadataBehavior 行為。接下來將分別示範組態與程式設計兩種實作路徑。

三、組態檔實作中繼資料交換

3.1 啟用 HTTP-GET 中繼資料

在 <serviceBehaviors> 中設定 httpGetEnabled="true",並指定基底位址:

<service name="WcfServiceApp.WCFService" behaviorConfiguration="WcfServiceApp.WCFServiceBehavior">
  <host>
    <baseAddresses>
      <add baseAddress="https://localhost:8001/" />
    </baseAddresses>
  </host>
</service>

<behaviors>
  <serviceBehaviors>
    <behavior name="WcfServiceApp.WCFServiceBehavior">
      <serviceMetadata httpGetEnabled="true" />
      <serviceDebug includeExceptionDetailInFaults="false" />
    </behavior>
  </serviceBehaviors>
</behaviors>

瀏覽器輸入基底位址即可查看服務說明頁面:

HTTP-GET 中繼資料瀏覽畫面

3.2 配置 MEX 端點(支援 HTTP/TCP/IPC)

新增三個 <endpoint>,契約均為 IMetadataExchange,並對應不同繫結與基底位址:

<service name="WCFService.WCFService" behaviorConfiguration="WCFService.WCFServiceBehavior">
  <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
  <endpoint address="mex" binding="mexTcpBinding" contract="IMetadataExchange" />
  <endpoint address="mex" binding="mexNamedPipeBinding" contract="IMetadataExchange" />
  <host>
    <baseAddresses>
      <add baseAddress="https://localhost:8001/" />
      <add baseAddress="net.tcp://localhost:8002/" />
      <add baseAddress="net.pipe://localhost/" />
    </baseAddresses>
  </host>
</service>

<serviceBehaviors>
  <behavior name="WCFService.WCFServiceBehavior">
    <serviceMetadata httpGetEnabled="true" />
    <serviceDebug includeExceptionDetailInFaults="false" />
  </behavior>
</serviceBehaviors>

四、程式碼實作中繼資料交換

程式設計方式雖較複雜,但能在執行期動態控制中繼資料發佈行為,彈性更高。需引用 System.ServiceModel.Description 命名空間。

4.1 HTTP-GET 程式化啟用

ServiceMetadataBehavior metadataBehavior = host.Description.Behaviors.Find<ServiceMetadataBehavior>();
if (metadataBehavior == null)
{
    metadataBehavior = new ServiceMetadataBehavior();
    host.Description.Behaviors.Add(metadataBehavior);
}
metadataBehavior.HttpGetEnabled = true;
metadataBehavior.HttpGetUrl = new Uri("https://localhost:8001/");

4.2 MEX 端點程式化新增(HTTP/TCP/IPC)

// 定義三種傳輸繫結元素
BindingElement tcpBindingElement = new TcpTransportBindingElement();
BindingElement httpBindingElement = new HttpsTransportBindingElement(); // 注意:原文為 HttpsTransportBindingElement,實際常用 HttpTransportBindingElement
BindingElement pipeBindingElement = new NamedPipeTransportBindingElement();

// 建立自訂繫結
Binding tcpBinding = new CustomBinding(tcpBindingElement);
Binding httpBinding = new CustomBinding(httpBindingElement);
Binding pipeBinding = new CustomBinding(pipeBindingElement);

// 服務基底位址
Uri tcpBaseAddress = new Uri("net.tcp://localhost:9001/");
Uri httpBaseAddress = new Uri("https://localhost:9002/");
Uri pipeBaseAddress = new Uri("net.pipe://localhost/");

// 新增服務端點
host.AddServiceEndpoint(typeof(WCFService.IWCFService), new NetTcpBinding(), tcpBaseAddress);
host.AddServiceEndpoint(typeof(WCFService.IWCFService), new WSHttpBinding(), httpBaseAddress);
host.AddServiceEndpoint(typeof(WCFService.IWCFService), new NetNamedPipeBinding(), pipeBaseAddress);

// 確保中繼資料行為存在
ServiceMetadataBehavior metadataBehavior = host.Description.Behaviors.Find<ServiceMetadataBehavior>();
if (metadataBehavior == null)
{
    metadataBehavior = new ServiceMetadataBehavior();
    host.Description.Behaviors.Add(metadataBehavior);
}

// 新增 MEX 端點
host.AddServiceEndpoint(typeof(IMetadataExchange), tcpBinding, "mex");
host.AddServiceEndpoint(typeof(IMetadataExchange), httpBinding, "mex");
host.AddServiceEndpoint(typeof(IMetadataExchange), pipeBinding, "mex");

五、驗證與總結

啟動宿主程式後,用戶端以不同中繼資料位址加入服務參考,均可成功解析服務契約:

  • HTTP-GET 方式:HTTP-GET 驗證結果
  • MEX HTTP 端點:MEX HTTP 驗證結果
  • MEX TCP 端點:MEX TCP 驗證結果
  • MEX Named Pipe 端點:MEX IPC 驗證結果

核心結論

  1. 中繼資料包含服務、資料、操作契約,以及交易、可靠傳訊、錯誤處理等進階資訊。
  2. 基於 XML 的中繼資料實現跨語言、跨平台服務互通,達成平台無關性。
  3. 透過中繼資料反序列化產生本地 Proxy,實現用戶端與服務端解耦,降低系統耦合度,優於傳統組件直接引用方式。

掌握 HTTP-GET 與 MEX 多協定配置與程式化控制,即可在實際專案中靈活部署 WCF 服務中繼資料交換,奠定異構系統整合的堅實基礎。

文章來源:https://www.cnblogs.com/frank_xl/

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved