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

WCF 深度之旅(13):打造 SOAP 訊息攔截轉發工具——Untyped Message、Operation Selection 與 AddressFilterMode.Any 實戰

     編輯:關於.NET

WCF 以訊息為核心,中介節點可攔截/路由/審計訊息。本文從零建立一個 **通用訊息攔截服務**,置於 Client 與 Service 之間,透明捕獲並顯示 Request/Response SOAP 訊息,深度演示 Message 類型、Action="*"、AddressFilterMode.Any、ClientViaBehavior 核心機制。

攔截服務契約設計

[ServiceContract]
public interface IIntercept {
  [OperationContract(Action = "*", ReplyAction = "*")]
  Message Intercept(Message request);
}

關鍵點:

  • 參數/回傳皆為 Message:無類型訊息,支援任意合約/操作/參數結構。
  • Action/ReplyAction = "*":匹配**任意** SOAP Action,繞過預設 Operation Selection(依 Action 標頭路由)。

Operation Selection 原理

預設規則:{Namespace}/{Contract}/{Method} = SOAP Action 標頭。
設 `Action="*"` 使攔截器成為**萬用操作**,接收所有訊息。

攔截服務實作

[ServiceBehavior(UseSynchronizationContext = false, AddressFilterMode = AddressFilterMode.Any)]
public class InterceptService : IIntercept {
  const string TargetEndpoint = "calculateService"; // 目標服務端點名稱
  public static SynchronizationContext SyncCtx { get; set; }
  public static TextBox DisplayPanel { get; set; }

  public Message Intercept(Message request) {
    // 1. 建立目標服務代理(同樣用 IIntercept 契約,因參數皆為 Message)
    var factory = new ChannelFactory(TargetEndpoint);
    var target = factory.CreateChannel();

    // 2. 訊息緩衝複製:避免狀態流轉導致無法重讀
    var reqBuffer = request.CreateBufferedCopy(int.MaxValue);
    var response = target.Intercept(reqBuffer.CreateMessage());

    var respBuffer = response.CreateBufferedCopy(int.MaxValue);

    // 3. UI 執行緒顯示
    SyncCtx.Post(_ => {
      DisplayPanel.Text += $"Request:{Environment.NewLine}{request}{Environment.NewLine}";
      DisplayPanel.Text += $"Response:{Environment.NewLine}{response}{Environment.NewLine}";
    }, null);

    // 4. 回傳複製訊息(原訊息已關閉)
    return respBuffer.CreateMessage();
  }
}

關鍵技術點

  1. AddressFilterMode.Any:忽略 SOAP To 標頭檢查,允許攔截器接收非寫給自己的訊息(Client 發給目標服務的訊息)。
  2. UseSynchronizationContext=false:避免 UI 執行緒綁定導致併發序列化。
  3. CreateBufferedCopy:Message 狀態機制,讀取後狀態變為 Read,不可再次讀取/傳輸。必須緩衝複製後重建。
  4. 同步上下文跨執行緒更新 UI:WinForms 需 `SynchronizationContext.Post` 封送至 UI 執行緒。

宿主配置 (WinForms)

<system.serviceModel>
  <bindings>
    <customBinding>
      <binding name="MyBinding">
        <textMessageEncoding />
        <httpTransport manualAddressing="true" /> // 關鍵:允許代理控制實際發送地址
      </binding>
    </customBinding>
  </bindings>
  <client>
    <endpoint address="https://127.0.0.1:9999/calculateservice" 
              binding="customBinding" bindingConfiguration="MyBinding"
              contract="IIntercept" name="calculateService" />
  </client>
  <services>
    <service name="InterceptService">
      <endpoint address="https://127.0.0.1:8888/Interceptservice"
                binding="customBinding" bindingConfiguration="MyBinding"
                contract="IIntercept" />
    </service>
  </services>
</system.serviceModel>

manualAddressing="true" 允許攔截器在轉發時保持原訊息 To 標頭不變。

客戶端注入攔截:ClientViaBehavior

<behaviors>
  <endpointBehaviors>
    <behavior name="viaBehavior">
      <clientVia viaUri="https://127.0.0.1:8888/Interceptservice" />
    </behavior>
  </endpointBehaviors>
</behaviors>
<client>
  <endpoint address="https://127.0.0.1:9999/calculateservice" 
            behaviorConfiguration="viaBehavior"
            binding="customBinding" ... contract="ICalculate" />
</client>

Client 邏輯呼叫 9999,實際發送至 8888 攔截器,攔截器轉發至 9999,回應原路返回。

運行效果

WinForms 介面即時顯示完整 HTTP/SOAP 封包:

POST /calculateservice HTTP/1.1
Content-Type: application/soap+xml; charset=utf-8
...

  
    https://tempuri.org/ICalculate/Add
    https://127.0.0.1:9999/calculateservice
  
  12

架構價值與擴展

能力實現方式
訊息審計/記錄攔截器持久化 Request/Response
動態路由/負載平衡根據訊息內容決定目標端點
協定轉換HTTP ↔ TCP、SOAP ↔ JSON
安全驗證/加解密攔截器統一處理 WS-Security
測試模擬/故障注入攔截器返回模擬回應/延遲/錯誤

此工具展示 WCF 訊息層擴展威力,是建構 ESB、API Gateway、服務網格控制平面的基石。

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