路由服務提供一般插入式SOAP媒介,能夠根據訊息內容路由訊息。 透過路由服務,您可以建立複雜的路由邏輯,讓您實作服務匯總、服務版本設定、優先順序路由和多播路由等案例。 路由服務也提供錯誤處理,可讓您設定備份端點的清單,如果傳送至主要目的地端點時發生失敗,則會傳送訊息。
本主題適用於路由服務新手,並涵蓋路由服務的基本設定和裝載。
設定
路由服務會實作為 WCF 服務,此服務會公開一或多個服務端點,以接收來自用戶端應用程式的訊息,並將訊息路由傳送至一或多個目的地端點。 服務會提供一個 RoutingBehavior,並將其應用於服務所公開的端點。 此行為可用來設定服務運作方式的各種層面。 為了方便設定使用組態檔, 在 RoutingBehavior 上指定參數。 在程式代碼型案例中,這些參數會指定為 物件的一 RoutingConfiguration 部分,然後可以傳遞至 RoutingBehavior。
開始時,此行為會將用來執行訊息 SOAP 處理的 SoapProcessingBehavior 新增到用戶端端點。 這可讓路由服務將訊息傳送至需要與訊息接收端點不同的 MessageVersion 端點。 RoutingBehavior 也會註冊一個服務擴充功能 RoutingExtension,該擴充功能提供一個可存取點,以便在執行時修改路由服務的設定。
RoutingConfiguration 類別提供一致的方法來設定和更新路由服務的組態。 它包含作為路由服務設定的參數,用於服務啟動時配置 路由行為 ,或傳遞給 路由擴充 以在執行時修改路由配置。
用來執行訊息內容型路由的路由邏輯是藉由將多個 MessageFilter 物件組合成篩選表(MessageFilterTable<TFilterData> 物件)來定義。 內送訊息會根據篩選數據表中包含的訊息篩選進行評估,以及針對符合訊息的每個 MessageFilter ,轉送至目的地端點。 應該用來路由訊息的篩選數據表,是在組態中使用 RoutingBehavior, 或使用 RoutingConfiguration 物件透過程式代碼來指定。
定義端點
雖然您可能應該藉由定義您將使用的路由邏輯來啟動設定,但您的第一個步驟實際上應該是判斷您要路由訊息的端點形狀。 路由服務會使用合約來定義用來接收和傳送訊息之通道的形狀,因此輸入通道的形狀必須符合輸出通道的圖形。 例如,如果您要路由至使用要求-回復通道圖形的端點,則必須在輸入端點上使用相容的合約,例如 IRequestReplyRouter。
這表示,如果您的目的地端點使用合約搭配多個通訊模式(例如混合單向和雙向作業),則您無法建立單一服務端點,以接收訊息並將其路由傳送至所有端點。 您必須判斷哪些端點具有相容的圖形,並定義一或多個服務端點,以用來接收要路由傳送至目的地端點的訊息。
備註
使用指定多個通訊模式的合約時(例如混合單向和雙向作業),可以在路由服務中使用雙向合約,例如 IDuplexSessionRouter。 不過,這表示系結必須能夠進行雙工通訊,這可能無法用於所有案例。 在不可能的情況下,將通訊分解成多個端點,或修改應用程式可能是必要的。
如需路由合約的詳細資訊,請參閱 路由合約。
定義服務端點之後,您可以使用 RoutingBehavior 將特定的 RoutingConfiguration 與端點產生關聯。 使用組態檔設定路由服務時, 會使用 RoutingBehavior 來指定篩選數據表,其中包含用來處理此端點上所接收訊息的路由邏輯。 如果您要以程式設計方式設定路由服務,您可以使用 RoutingConfiguration 來指定篩選數據表。
下列範例會定義路由服務以程序設計方式和使用組態檔所使用的服務和用戶端端點。
<services>
<!--ROUTING SERVICE -->
<service behaviorConfiguration="routingData"
name="System.ServiceModel.Routing.RoutingService">
<host>
<baseAddresses>
<add baseAddress="http://localhost:8000/routingservice/router"/>
</baseAddresses>
</host>
<!-- Define the service endpoints that are receive messages -->
<endpoint address=""
binding="wsHttpBinding"
name="reqReplyEndpoint"
contract="System.ServiceModel.Routing.IRequestReplyRouter" />
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="routingData">
<serviceMetadata httpGetEnabled="True"/>
<!-- Add the RoutingBehavior and specify the Routing Table to use -->
<routing filterTableName="routingTable1" />
</behavior>
</serviceBehaviors>
</behaviors>
<client>
<!-- Define the client endpoint(s) to route messages to -->
<endpoint name="CalculatorService"
address="http://localhost:8000/servicemodelsamples/service"
binding="wsHttpBinding" contract="*" />
</client>
//set up some communication defaults
string clientAddress = "http://localhost:8000/servicemodelsamples/service";
string routerAddress = "http://localhost:8000/routingservice/router";
Binding routerBinding = new WSHttpBinding();
Binding clientBinding = new WSHttpBinding();
//add the endpoint the router uses to receive messages
serviceHost.AddServiceEndpoint(
typeof(IRequestReplyRouter),
routerBinding,
routerAddress);
//create the client endpoint the router routes messages to
ContractDescription contract = ContractDescription.GetContract(
typeof(IRequestReplyRouter));
ServiceEndpoint client = new ServiceEndpoint(
contract,
clientBinding,
new EndpointAddress(clientAddress));
//create a new routing configuration object
RoutingConfiguration rc = new RoutingConfiguration();
….
rc.FilterTable.Add(new MatchAllMessageFilter(), endpointList);
//attach the behavior to the service host
serviceHost.Description.Behaviors.Add(
new RoutingBehavior(rc));
此範例會將路由服務設定為公開具有 位址 http://localhost:8000/routingservice/router的單一端點,用來接收要路由的訊息。 由於訊息會路由傳送至要求-回復端點,因此服務端點會使用 IRequestReplyRouter 合約。 此組態也會定義一個單一客戶端端點 http://localhost:8000/servicemodelsample/service,以路由傳遞訊息。 名為 「routingTable1」 的篩選資料表 (未顯示) 包含路由邏輯,用來路由訊息,並使用 RoutingBehavior (適用於組態檔) 或 RoutingConfiguration (針對程式設計設定)與服務端點相關聯。
路由邏輯
若要定義用來路由訊息的路由邏輯,您必須判斷傳入訊息中包含的哪些資料可以被獨特地處理。 例如,如果您要路由的所有目的地端點共用相同的SOAP動作,則訊息中包含的動作值並不是訊息應路由傳送至哪個特定端點的良好指標。 如果您必須唯一地將訊息路由傳送至一個特定端點,您應該篩選可唯一識別訊息路由傳送目的地端點的數據。
路由服務提供數個 MessageFilter 實作,可檢查訊息內的特定值,例如地址、動作、端點名稱,甚至是 XPath 查詢。 如果這些實作都不符合您的需求,您可以建立自定義 MessageFilter 實作。 如需訊息篩選和路由服務所使用實作比較的詳細資訊,請參閱 訊息篩選 和 選擇篩選。
多個訊息篩選會組織成篩選數據表,讓每個 MessageFilter 與目的地端點產生關聯。 或者,篩選數據表也可用來指定路由服務在傳輸失敗時嘗試將訊息傳送至的備份端點清單。
根據預設,篩選數據表中的所有訊息篩選都會同時評估;不過,您可以指定 Priority ,以特定順序評估訊息篩選。 系統會先評估優先順序最高的所有專案,如果找到較高優先順序層級的相符專案,則不會評估優先順序較低的訊息篩選。 如需篩選數據表的詳細資訊,請參閱 訊息篩選。
下列範例會使用MatchAllMessageFilter,它會對所有訊息評估為true。 此 MessageFilter 會新增至 “routingTable1” 篩選數據表,其會將 MessageFilter 與名為 “CalculatorService” 的用戶端端點產生關聯。
RoutingBehavior 接著指定此資料表應該用來路由服務端點處理的訊息。
<behaviors>
<serviceBehaviors>
<behavior name="routingData">
<serviceMetadata httpGetEnabled="True"/>
<!-- Add the RoutingBehavior and specify the Routing Table to use -->
<routing filterTableName="routingTable1" />
</behavior>
</serviceBehaviors>
</behaviors>
<!--ROUTING SECTION -->
<routing>
<filters>
<filter name="MatchAllFilter1" filterType="MatchAll" />
</filters>
<filterTables>
<table name="routingTable1">
<filters>
<add filterName="MatchAllFilter1" endpointName="CalculatorService" />
</filters>
</table>
</filterTables>
</routing>
//create a new routing configuration object
RoutingConfiguration rc = new RoutingConfiguration();
//create the endpoint list that contains the endpoints to route to
//in this case we have only one
List<ServiceEndpoint> endpointList = new List<ServiceEndpoint>();
endpointList.Add(client);
//add a MatchAll filter to the Router's filter table
//map it to the endpoint list defined earlier
//when a message matches this filter, it is sent to the endpoint contained in the list
rc.FilterTable.Add(new MatchAllMessageFilter(), endpointList);
備註
根據預設,路由服務只會評估訊息的標頭。 若要允許篩選條件存取訊息本文,您必須將 設定 RouteOnHeadersOnly 為 false。
多播
雖然許多路由服務組態使用僅將訊息路由傳送至一個特定端點的獨佔篩選邏輯,但您可能需要將指定的訊息路由傳送至多個目的地端點。 若要將訊息多播至多個目的地,下列條件必須成立:
通道類型不得為請求-回覆(雖然可以是單向或雙向),因為用戶端應用程式只能收到一個回覆來回應該請求。
在評估訊息時,多個篩選器必須返回
true。
如果符合這些條件,訊息會路由傳送至評估為 true的所有篩選條件的所有端點。 下列範例會定義路由組態,如果訊息中的端點位址為 http://localhost:8000/routingservice/router/rounding,則會導致訊息路由傳送至這兩個端點。
<!--ROUTING SECTION -->
<routing>
<filters>
<filter name="MatchAllFilter1" filterType="MatchAll" />
<filter name="RoundingFilter1" filterType="EndpointAddress"
filterData="http://localhost:8000/routingservice/router/rounding" />
</filters>
<filterTables>
<table name="routingTable1">
<filters>
<add filterName="MatchAllFilter1" endpointName="CalculatorService" />
<add filterName="RoundingFilter1" endpointName="RoundingCalcService" />
</filters>
</table>
</filterTables>
</routing>
rc.FilterTable.Add(new MatchAllMessageFilter(), calculatorEndpointList);
rc.FilterTable.Add(new EndpointAddressMessageFilter(new EndpointAddress(
"http://localhost:8000/routingservice/router/rounding")),
roundingCalcEndpointList);
SOAP 處理
為了支援不同通訊協定之間的訊息路由, RoutingBehavior 預設會將 新增 SoapProcessingBehavior 至所有路由傳送訊息的用戶端端點。 此行為會在將訊息路由至端點之前自動建立新的 MessageVersion ,以及在將訊息傳回要求用戶端應用程式之前,先為任何回應檔建立相容的 MessageVersion 。
為輸出訊息建立新 MessageVersion 所採取的步驟如下:
要求處理
取得 MessageVersion 的輸出系結/通道。
取得原始訊息的本文檢視器。
建立一則具有相同動作、內文讀取器和新 MessageVersion 的訊息。
如果 Addressing != Addressing.None,請將 To、From、FaultTo 和 RelatesTo 標頭複製到新訊息。
將所有訊息屬性複製到新的訊息。
儲存處理回應時要使用的原始要求訊息。
傳回新的要求訊息。
回應處理
取得原始要求訊息的 MessageVersion 。
取得已接收回應訊息的本文讀取器。
建立具有相同動作、本文讀取器和原始要求訊息的MessageVersion的新回應訊息。
如果 Addressing != Addressing.None,請將 To、From、FaultTo 和 RelatesTo 標頭複製到新訊息。
將訊息屬性複製到新的訊息。
傳回新的回應消息。
根據預設, SoapProcessingBehavior 會在服務啟動時自動新增至用戶端端點 RoutingBehavior ;不過,您可以使用 屬性來控制SOAP處理是否新增至所有用戶端端點 SoapProcessingEnabled 。 如果需要更細微的 SOAP 處理控制,您也可以將行為直接新增至特定端點,並在端點層級啟用或停用此行為。
備註
如果針對需要與原始要求訊息不同的 MessageVersion 的端點停用 SOAP 處理,您必須提供自定義機制來執行任何必要的 SOAP 修改,再將訊息傳送至目的地端點。
在下列範例中, soapProcessingEnabled 屬性是用來防止 SoapProcessingBehavior 自動新增至所有用戶端端點。
<behaviors>
<!--default routing service behavior definition-->
<serviceBehaviors>
<behavior name="routingConfiguration">
<routing filterTableName="filterTable1" soapProcessingEnabled="false"/>
</behavior>
</serviceBehaviors>
</behaviors>
//create the default RoutingConfiguration
RoutingConfiguration rc = new RoutingConfiguration();
rc.SoapProcessingEnabled = false;
動態設定
當你新增額外的用戶端端點,或需要修改用於訊息路由的過濾器時,你必須有辦法在執行時動態更新設定,以防止服務中斷到目前透過路由服務接收訊息的端點。 修改組態檔或主應用程式的程式代碼並不一定足夠,因為任一種方法都需要回收應用程式,這會導致目前傳輸中任何訊息可能遺失,以及等候服務重新啟動時可能會停機。
您只能以程序設計方式修改 RoutingConfiguration 。 雖然你可以一開始用設定檔來設定服務,但你只能在執行時透過建構新的 RoutingConfiguration 並將其作為參數傳給 ApplyConfiguration 服務擴充包所暴露 RoutingExtension 的方法來修改設定。 目前傳輸中的任何訊息會繼續使用先前的設定路由傳送,而在呼叫 ApplyConfiguration 之後收到的訊息會使用新的組態。 下列範例示範如何建立路由服務的實例,然後接著修改組態。
RoutingConfiguration routingConfig = new RoutingConfiguration();
routingConfig.RouteOnHeadersOnly = true;
routingConfig.FilterTable.Add(new MatchAllMessageFilter(), endpointList);
RoutingBehavior routing = new RoutingBehavior(routingConfig);
routerHost.Description.Behaviors.Add(routing);
routerHost.Open();
// Construct a new RoutingConfiguration
RoutingConfiguration rc2 = new RoutingConfiguration();
ServiceEndpoint clientEndpoint = new ServiceEndpoint();
ServiceEndpoint clientEndpoint2 = new ServiceEndpoint();
// Add filters to the FilterTable in the new configuration
rc2.FilterTable.add(new MatchAllMessageFilter(),
new List<ServiceEndpoint>() { clientEndpoint });
rc2.FilterTable.add(new MatchAllMessageFilter(),
new List<ServiceEndpoint>() { clientEndpoint2 });
rc2.RouteOnHeadersOnly = false;
// Apply the new configuration to the Routing Service hosted in
routerHost.routerHost.Extensions.Find<RoutingExtension>().ApplyConfiguration(rc2);
備註
以這種方式更新路由服務時,只能傳遞新的組態。 無法只修改目前組態的選定元素,或將新項目附加至目前的組態;您必須建立並傳遞一個用以取代現有組態的新組態。
備註
使用先前設定開啟的任何會話會繼續使用先前的設定。 新的配置僅用於新的會話。
錯誤處理
如果在嘗試傳送訊息時遇到任何 CommunicationException,就會啟動錯誤處理。 這些例外狀況通常表示嘗試與定義的用戶端端點通訊時發生問題,例如 EndpointNotFoundException、 ServerTooBusyException或 CommunicationObjectFaultedException。 錯誤處理程式碼也會攔截並嘗試重試傳送發生 TimeoutException 這種常見例外狀況,這種例外狀況並不是源自於 CommunicationException。
發生上述其中一個例外狀況時,路由服務會切換至備援端點的清單。 如果所有備份端點都因通訊失敗而失敗,或端點傳回指出目的地服務內失敗的例外狀況,路由服務會將錯誤傳回用戶端應用程式。
備註
錯誤處理功能會擷取並處理嘗試傳送訊息時以及嘗試關閉通道時所發生的例外狀況。 錯誤處理程式代碼不是用來偵測或處理它所通訊之應用程式端點所建立的例外狀況; FaultException 由服務擲回的 會以 FaultMessage 的形式出現在路由服務,並流回用戶端。
如果路由服務嘗試轉送訊息時發生錯誤,您可能會在用戶端上收到 FaultException ,而不是在沒有路由服務時通常會得到的 EndpointNotFoundException。 因此,路由服務可能會遮罩例外狀況,除非您檢查巢狀例外狀況,否則不會提供完整的透明度。
追蹤例外狀況
將訊息傳送至清單中的端點失敗時,路由服務會追蹤產生的例外狀況數據,並將例外狀況詳細數據附加為名為 Exceptions 的訊息屬性。 這會保留例外狀況數據,並允許使用者透過訊息偵測器以程序設計方式存取。 例外狀況數據會按照每個訊息儲存在字典中,該字典將端點名稱與嘗試傳送訊息時遇到的例外狀況詳細數據對應起來。
備份端點
篩選表中的每個篩選條目可以選擇性地指定一個備用端點清單,以備在傳送至主要端點失敗時使用。 如果發生這類失敗,路由服務會嘗試將訊息傳輸到備份端點清單中的第一個項目。 如果此傳送嘗試也發生傳輸失敗,則會嘗試備份清單中的下一個端點。 路由服務會繼續將訊息傳送至清單中的每個端點,直到訊息成功接收、所有端點都傳回傳輸失敗,或端點傳回非傳輸失敗為止。
下列範例會將路由服務設定為使用備份清單。
<routing>
<filters>
<!-- Create a MatchAll filter that catches all messages -->
<filter name="MatchAllFilter1" filterType="MatchAll" />
</filters>
<filterTables>
<!-- Set up the Routing Service's Message Filter Table -->
<filterTable name="filterTable1">
<!-- Add an entry that maps the MatchAllMessageFilter to the dead destination -->
<!-- If that endpoint is down, tell the Routing Service to try the endpoints -->
<!-- Listed in the backupEndpointList -->
<add filterName="MatchAllFilter1" endpointName="deadDestination" backupList="backupEndpointList"/>
</filterTable>
</filterTables>
<!-- Create the backup endpoint list -->
<backupLists>
<!-- Add an endpoint list that contains the backup destinations -->
<backupList name="backupEndpointList">
<add endpointName="realDestination" />
<add endpointName="backupDestination" />
</backupList>
</backupLists>
</routing>
//create the endpoint list that contains the service endpoints we want to route to
List<ServiceEndpoint> backupList = new List<ServiceEndpoint>();
//add the endpoints in the order that the Routing Service should contact them
//first add the endpoint that we know is down
//clearly, normally you wouldn't know that this endpoint was down by default
backupList.Add(fakeDestination);
//then add the real Destination endpoint
//the Routing Service attempts to send to this endpoint only if it
//encounters a TimeOutException or CommunicationException when sending
//to the previous endpoint in the list.
backupList.Add(realDestination);
//add the backupDestination endpoint
//the Routing Service attempts to send to this endpoint only if it
//encounters a TimeOutException or CommunicationsException when sending
//to the previous endpoints in the list
backupList.Add(backupDestination);
//create the default RoutingConfiguration option
RoutingConfiguration rc = new RoutingConfiguration();
//add a MatchAll filter to the Routing Configuration's filter table
//map it to the list of endpoints defined above
//when a message matches this filter, it is sent to the endpoints in the list in order
//if an endpoint is down or does not respond (which the first endpoint won't
//since the client does not exist), the Routing Service automatically moves the message
//to the next endpoint in the list and try again.
rc.FilterTable.Add(new MatchAllMessageFilter(), backupList);
支援的錯誤模式
下表描述與使用備份端點清單相容的模式,以及描述特定模式錯誤處理詳細數據的附註。
| 樣式 | 會期 | 交易 | 接收上下文 | 支援的備份清單 | 註釋 |
|---|---|---|---|---|---|
| One-Way | 是的 | 嘗試在備份端點上重新傳送訊息。 如果此訊息是多播,則只有失敗通道上的訊息會移至其備份目的地。 | |||
| One-Way | ✔️ | 否 | 擲回例外狀況並回復交易。 | ||
| One-Way | ✔️ | 是的 | 嘗試在備份端點上重新傳送訊息。 成功接收訊息後,請完成所有接收上下文。 如果訊息未由任何端點成功接收,請勿完成接收上下文。 當此訊息被多播時,只有在至少一個端點成功接收到訊息後(無論是主要或備份),接收上下文才會被完成。 如果任何多播路徑中的任何端點都無法成功接收消息,請勿完成接收上下文。 |
||
| One-Way | ✔️ | ✔️ | 是的 | 中止先前的交易、建立新的交易,然後重新傳送所有訊息。 發生錯誤的訊息會傳送至備份目的地。 在建立交易並確保所有傳輸成功之後,完成接收上下文並認可交易。 |
|
| One-Way | ✔️ | 是的 | 嘗試在備份端點上重新傳送訊息。 在多播情形中,僅重新發送會話中遇到錯誤或會話關閉失敗的訊息到備份目的地。 | ||
| One-Way | ✔️ | ✔️ | 否 | 擲回例外狀況並回復交易。 | |
| One-Way | ✔️ | ✔️ | 是的 | 嘗試在備份端點上重新傳送訊息。 在所有訊息傳送完成且沒有錯誤之後,會話會指出沒有更多訊息,而路由服務會成功關閉所有輸出會話通道、所有接收內容都已完成,且輸入會話通道已關閉。 | |
| One-Way | ✔️ | ✔️ | ✔️ | 是的 | 中止目前的交易,並建立新的交易。 重新傳送會話中的所有先前訊息。 建立一筆交易之後,該交易中所有訊息已成功傳送,當會話框顯示不再有訊息時,所有的輸出會話通道都會被關閉,接收內容都與該交易一併完成,輸入會話通道會被關閉,並且交易會被認可。 當會話進行多播時,沒有錯誤的訊息會重新傳送至與之前相同的目的地,且發生錯誤的訊息會傳送至備份目的地。 |
| Two-Way | 是的 | 傳送至備份目的地。 通道傳回回應消息之後,將回應傳回原始用戶端。 | |||
| Two-Way | ✔️ | 是的 | 將通道上的所有訊息傳送至備份目的地。 通道傳回回應消息之後,將回應傳回原始用戶端。 | ||
| Two-Way | ✔️ | 否 | 擲回例外狀況並回復交易。 | ||
| Two-Way | ✔️ | ✔️ | 否 | 擲回例外狀況並回復交易。 | |
| 雙層式 | 否 | 目前不支援非會話雙工通訊。 | |||
| 雙層式 | ✔️ | 是的 | 傳送至備份目的地。 |
Hosting
因為路由服務會實作為 WCF 服務,所以它必須自我裝載於應用程式內,或由 IIS 或 WAS 裝載。 建議您在 IIS、WAS 或 Windows 服務應用程式中裝載路由服務,以利用這些裝載環境中可用的自動啟動和生命週期管理功能。
下列範例示範如何在應用程式中裝載路由服務。
using (ServiceHost serviceHost =
new ServiceHost(typeof(RoutingService)))
若要在 IIS 或 WAS 內裝載路由服務,您必須建立服務檔案 (.svc) 或使用以組態為基礎的啟用服務。 使用服務檔案時,您必須使用 Service 參數來指定 RoutingService 。 下列範例包含範例服務檔案,可用來使用 IIS 或 WAS 裝載路由服務。
<%@ ServiceHost Language="C#" Debug="true" Service="System.ServiceModel.Routing.RoutingService,
System.ServiceModel.Routing, version=4.0.0.0, Culture=neutral,
PublicKeyToken=31bf3856ad364e35" %>
路由服務和冒用
WCF 路由服務可以與身份模擬搭配使用,以傳送和接收訊息。 所有通常 Windows 冒充的限制條件都適用。 如果您需要在撰寫自己的服務時設定服務或帳戶許可權以使用模擬,則必須執行這些相同的步驟,才能搭配路由服務使用模擬。 如需詳細資訊,請參閱委派和模擬。
使用路由服務的冒充需要在 ASP.NET 相容性模式中使用 ASP.NET 冒充,或使用已設定為允許冒充的 Windows 憑證。 如需 ASP.NET 相容性模式的詳細資訊,請參閱 WCF 服務和 ASP.NET。
警告
WCF 路由服務不支援使用基本身份驗證進行模仿。
若要搭配路由服務使用 ASP.NET 模擬,請在服務裝載環境中啟用 ASP.NET 相容性模式。 路由服務已標示為允許 ASP.NET 相容性模式,並會自動啟用模擬。 冒充是唯一支援的 ASP.NET 與路由服務整合。
若要搭配路由服務使用 Windows 認證模擬,您需要同時設定認證和服務。 用戶端認證物件(可從WindowsClientCredential存取的ChannelFactory)定義了一個AllowedImpersonationLevel屬性,該屬性必須設定為允許冒用。 最後,在服務上,您需要將ServiceAuthorizationBehavior行為設定為ImpersonateCallerForAllOperations並設置為true。 路由服務會使用此旗標來決定是否要建立用於轉送訊息且啟用身份模擬的客戶端。