WCF 接收訊息時,透過訊息篩選引擎決定目標端點。核心兩大組件:
MessageFilter 抽象基類,判斷訊息是否匹配條件IMessageFilterTable<TFilterData>,儲存篩選器鍵值對,支援優先級每個 EndpointDispatcher 持有兩個篩選器:地址篩選器(檢查 To 標頭與尋址標頭)與契約篩選器(檢查 Action 標頭)。
| 篩選器 | 用途 | 匹配邏輯 |
|---|---|---|
| EndpointAddressMessageFilter | 預設地址篩選器 | To 標頭與 EndpointAddress 完全匹配,且所有必要尋址標頭存在 |
| ActionMessageFilter | 預設契約篩選器 | Action 標頭與操作清單任一匹配;清單空則全匹配 |
| PrefixEndpointAddressMessageFilter | 前綴地址匹配 | To 標頭 URI 以篩選器 URI 為前綴(最長前綴匹配) |
| MatchAllMessageFilter | 全匹配 | 永遠回傳 true(訊息非 null) |
| MatchNoneMessageFilter | 全不匹配 | 永遠回傳 false(訊息非 null) |
| XPathMessageFilter | XPath 1.0 條件 | 依 XPath 運算式評估訊息內容 |

var actionFilter1 = new ActionMessageFilter("Add", "Sub");
var actionFilter2 = new ActionMessageFilter("Mul");
var addrFilter1 = new EndpointAddressMessageFilter(new EndpointAddress("https://localhost:8887/Calculator"));
var addrFilter2 = new EndpointAddressMessageFilter(new EndpointAddress("https://www.cnblogs.com/terrylee"));
var msg = Message.CreateMessage(MessageVersion.Soap12WSAddressing10, "myBody");
msg.Headers.Action = "Add";
msg.Headers.To = new Uri("https://localhost:8887/Calculator");
Console.WriteLine(actionFilter1.Match(msg)); // True
Console.WriteLine(actionFilter2.Match(msg)); // False
Console.WriteLine(addrFilter1.Match(msg)); // True
Console.WriteLine(addrFilter2.Match(msg)); // False

SOAP 訊息實際內容:
<s:Envelope ...>
<s:Header>
<a:To>https://localhost:8887/Calculator</a:To>
<a:Action>Add</a:Action>
</s:Header>
<s:Body></s:Body>
</s:Envelope>
依篩選器型別分桶存儲,新增時自動分配預設優先級:

篩選器條件建構後不可變,需建立新實例替換。
ServiceBehavior 屬性 AddressFilterMode 三選一:
EndpointAddressMessageFilterPrefixEndpointAddressMessageFilterMatchAllMessageFilter[ServiceBehavior(AddressFilterMode = AddressFilterMode.Prefix)]
public class CalculatorService : ICalculator { ... }
foreach (var cd in host.ChannelDispatchers)
foreach (var ed in cd.Endpoints)
Console.WriteLine($"AddrFilter: {ed.AddressFilter} | ContractFilter: {ed.ContractFilter}");

訊息篩選引擎是 WCF 訊息分派核心,內建篩選器涵蓋常見需求,AddressFilterMode 提供服務級快速切換,自訂篩選器(下篇主題)則支援任意複雜路由邏輯。