日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

WCF后传系列(3):深入WCF寻址Part 3—消息过滤引擎

發(fā)布時間:2024/4/13 编程问答 46 豆豆
生活随笔 收集整理的這篇文章主要介紹了 WCF后传系列(3):深入WCF寻址Part 3—消息过滤引擎 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

概述

通過前面兩篇的介紹,對Web服務尋址規(guī)范以及在WCF開發(fā)中終結點地址有了深入的認識。本文我們繼續(xù)深入WCF尋址第三部分內(nèi)容,當消息傳入時,如何來確定匹配的終結點,就是我們本文要講到的消息篩選引擎。在WCF中,消息篩選器引擎包括兩個重要的組成部分:篩選器和篩選器表。

認識消息篩選器

在WCF中當有消息傳入時,它使用消息篩選器來確定匹配的終結點,每個終結點實際上關聯(lián)著兩個篩選器:一個地址篩選器和一個契約篩選器。地址篩選器確定傳入消息是否匹配終結點的“To”地址和任何必需的地址報頭,而契約篩選器則確定它是否匹配終結點的契約,兩個篩選器都被調(diào)度程序用來確定目標終結點。 在WCF中,所有的消息篩選器都繼承于MessageFilter抽象基類,系統(tǒng)內(nèi)置了幾種的消息篩選器,如圖1所示: ?? 圖1 EndpointAddressMessageFilter:作為默認的地址篩選器,它會將SOAP消息中的“To”地址與終結點地址進行比較,預期它們完全匹配,也會傳入消息中獲得的尋址報頭和終結點要求的一組尋址報頭進行比較,要使最終匹配的結果返回true,必須滿足以下兩個條件: 1. 篩選器的地址統(tǒng)一資源標識符 (URI) 必須與消息 To 標頭中的統(tǒng)一資源標識符相同。 2. 篩選器地址中的每個終結點參數(shù)都必須在消息中找到一個與之匹配的標頭。 ActionMessageFilter:作為默認的契約篩選器,它根據(jù)傳入的SAOP消息中“Action”值和契約上的操作進行比較,確定是否匹配匹配。該篩選器在初始化時將包含一個操作字符串列表,如果篩選器的列表中的任一操作與消息或消息緩沖區(qū)中的 Action 標頭匹配,則 Match 方法返回 true。 如果該列表為空,則將該篩選器視為全匹配型篩選器,任何消息或消息緩沖區(qū)都與該篩選器匹配,并且 Match 返回 true。 如果篩選器列表中沒有任何操作與消息或消息緩沖區(qū)中的 Action 標頭匹配,則 Match 返回 false。 如果消息中不存在任何操作且篩選器的列表非空,則 Match 返回 false。 PrefixEndpointAddressMessageFilter:此篩選器與 EndpointAddressMessageFilter 執(zhí)行相同的查詢,不同的是測試消息是否與終結點地址相匹配是由“最長前綴匹配”完成的。這表示篩選器中指定的 URI 不需要與消息的 URI 完全匹配,不過必須作為前綴包含在該 URI 中。例如,如果篩選器指定地址“[url]http://www.foo.com[/url]”,并且消息是發(fā)送給“[url]http://www.foo.com/customerA[/url]”,則將滿足篩選器查詢條件的 URI 部分,但是篩選器查詢的報頭部分仍需要完成。 MatchAllMessageFilter:該篩選器將導致所有消息都匹配給定終結點,看一下它的Match方法實現(xiàn),除非消息為空,否則就返回True:[DataContract] public class MatchAllMessageFilter : MessageFilter {public override bool Match(Message message){if (message == null){throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("message");}return true;} } MatchNoneMessageFilter:該篩選器將導致所有消息都不匹配,看一下它的Match方法實現(xiàn),除非消息為空,否則就返回False:[DataContract] public class MatchNoneMessageFilter : MessageFilter {public override bool Match(Message message){if (message == null){throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("message");}return false;} } XpathMessageFilter:使用 XPath 1.0 表達式來指定匹配的條件。 除此之外,我們可以自定義自己的消息篩選器,在本系列的后面將會講到。

篩選器工作原理

正如在前面所看到的,MessageFilter提供了所有篩選器的基類,篩選器中的Match方法用于確定消息是否滿足篩選器的條件。如下面的代碼片段中,我們定義兩個ActionMessageFilter和EndpointAddressMessageFilter,然后創(chuàng)建一個Message,看看它們最終匹配的結果:static void Main(string[] args) {// 創(chuàng)建兩個ActionMessageFilter實例ActionMessageFilter actionFilter1 = new ActionMessageFilter("Add", "Sub");ActionMessageFilter actionFilter2 = new ActionMessageFilter("Mul");// 創(chuàng)建兩個EndpointAddressMessageFilter實例EndpointAddressMessageFilter addressFilter1 = new EndpointAddressMessageFilter(new EndpointAddress("http://localhost:8887/Calculator"));EndpointAddressMessageFilter addressFilter2 = new EndpointAddressMessageFilter(new EndpointAddress("http://www.cnblogs.com/terrylee"));// 創(chuàng)建一個Message,設置Action和ToMessage message = Message.CreateMessage(MessageVersion.Soap12WSAddressing10,"myBody");message.Headers.Action = "Add";message.Headers.To = new Uri("http://localhost:8887/Calculator");// 測試匹配結果bool actionResult1 = actionFilter1.Match(message);bool actionResult2 = actionFilter2.Match(message);bool addressResult1 = addressFilter1.Match(message);bool addressResult2 = addressFilter2.Match(message);// 輸出結果Console.WriteLine("The result of filter:");Console.WriteLine(actionResult1);Console.WriteLine(actionResult2);Console.WriteLine(addressResult1);Console.WriteLine(addressResult2);Console.ReadLine(); } 輸出結果如圖2所示: ?? 圖2 在該示例中,由于我們創(chuàng)建的Message對象,最終的SOAP消息包如下代碼所示:<s:Envelope xmlns:s="[url]http://www.w3.org/2003/05/soap-envelope[/url]"xmlns:a="[url]http://www.w3.org/2005/08/addressing[/url]"><s:Header><a:To s:mustUnderstand="1">[url]http://localhost:8887/Calculator[/url]</a:To><a:Action s:mustUnderstand="1">Add</a:Action></s:Header><s:Body></s:Body> </s:Envelope> 所以這里匹配上的是actionFilter1和addressFilter1。注意,一旦構造篩選器,篩選器使用的條件無法更改,因為篩選器表無法檢測更改。修改篩選器的條件的唯一方法是構造一個新的篩選器,然后刪除現(xiàn)有篩選器。

消息篩選器表

消息篩選器表用于存儲鍵-值對,其中篩選器為鍵,而與篩選器關聯(lián)的數(shù)據(jù)為值。篩選器數(shù)據(jù)可用于指示當消息與篩選器匹配時要采取的操作,篩選器數(shù)據(jù)的類型是篩選器表類的泛型參數(shù)。 篩選器數(shù)據(jù)可以包含路由規(guī)則、會話安全狀態(tài)、通道上的偵聽器等等。所有的消息篩選器都存儲在實現(xiàn)了IMessageFilterTable<TFilterData>的表中,如MessageFilterTable<TFilterData>,在它的內(nèi)部,又有很多個與具體篩選器類型相關的篩選器表,添加篩選器時,會將其放置在包含此類篩選器的內(nèi)部篩選器表(如果已存在)中。如果不存在此篩選器表,則調(diào)用 CreateFilterTable 以分配一個適當類型的新篩選器表,如圖3所示: ?? 圖3 同時在添加篩選器時,篩選器表會給每個篩選器設置一個默認的優(yōu)先級。

設置服務的消息篩選器

我們可以通過ServiceBehavior來指定服務所用的消息篩選器,在ServiceBehavior中有一個AddressFilterMode的屬性,它用來指定調(diào)度程序用于將傳入的消息路由到匹配的終結點,由三個選項: Exact:指示對傳入消息的地址執(zhí)行精確匹配的篩選器,即使用EndpointAddressMessageFilter。 Prefix:指示對傳入消息的地址執(zhí)行最長前綴匹配的篩選器,即使用PrefixEndpointAddressMessageFilter。 Any:指示與傳入消息的任意地址相匹配的篩選器,即使用MatchAllMessageFilter。 如下面的代碼,指示使用PrefixEndpointAddressMessageFilter作為地址篩選器:[ServiceBehavior(AddressFilterMode = AddressFilterMode.Prefix)] public class CalculatorService : ICalculator {public int Add(int x, int y){return x + y;} } 我們可以在Host端輸出一下EndpointDispatcher所用的地址篩選器和契約篩選器,如下代碼所示:static void Main(string[] args) {using (ServiceHost calculatorServiceHost =new ServiceHost(typeof(CalculatorService))){calculatorServiceHost.Opened += delegate{Console.WriteLine("Service begin to listen via the Address:{0}",calculatorServiceHost.BaseAddresses[0].ToString());};calculatorServiceHost.Open();foreach (ChannelDispatcher channelDispatcher incalculatorServiceHost.ChannelDispatchers){Console.WriteLine(channelDispatcher.BindingName);foreach (EndpointDispatcher endpointDispatcher inchannelDispatcher.Endpoints){Console.WriteLine(endpointDispatcher.AddressFilter.ToString());Console.WriteLine(endpointDispatcher.ContractFilter.ToString());}Console.WriteLine("---------------------------");}Console.Read();} } 輸出結果如圖4所示: ?? 圖4

結束語

本文詳細介紹了WCF中的消息篩選器,這在某些場景下非常有用,可以根據(jù)SOAP消息標頭中包含的數(shù)據(jù)將消息發(fā)送到不同的地方處理,這在一定程度上可以擺脫WCF的調(diào)度模型。WCF尋址相關文章: WCF專題系列(5):深入WCF尋址Part 5—邏輯地址和物理地址 WCF專題系列(4):深入WCF尋址Part 4—自定義消息篩選器 WCF專題系列(2):深入WCF尋址Part 2—自定義尋址報頭 WCF專題系列(1):深入WCF尋址Part 1—Web服務尋址規(guī)范
















本文轉自lihuijun51CTO博客,原文鏈接:http://blog.51cto.com/terrylee/151933?,如需轉載請自行聯(lián)系原作者



總結

以上是生活随笔為你收集整理的WCF后传系列(3):深入WCF寻址Part 3—消息过滤引擎的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。