行為可讓您修改預設行為,並新增自定義延伸模組,以檢查及驗證 Windows Communication Foundation (WCF) 客戶端和服務應用程式中的服務組態或修改運行時間行為。 本主題描述行為介面、如何實作它們,以及如何以程序設計方式或在組態檔中將其新增至服務描述(在服務應用程式中)或端點(在用戶端應用程式中)。 如需使用系統提供之行為的詳細資訊,請參閱 指定服務 Run-Time 行為 和 指定用戶端 Run-Time 行為。
行為
行為類型會新增至服務或服務端點描述物件(分別在服務或用戶端上),然後 Windows Communication Foundation (WCF) 使用這些物件來建立執行 WCF 服務或 WCF 用戶端的運行時間。 在運行時間建構程式期間呼叫這些行為時,它們就能夠存取修改合約、系結和位址所建構之運行時間的屬性和方法。
行為方法
所有行為都有 AddBindingParameters 方法、 ApplyDispatchBehavior 方法、 Validate 方法及方法 ApplyClientBehavior ,但有一個例外狀況:因為 IServiceBehavior 無法在用戶端中執行,所以不會實 ApplyClientBehavior作 。
使用
AddBindingParameters方法來修改或新增自訂物件到集合中,以便自訂繫結在運行時的建構過程中可以訪問和使用。 例如,這說明了如何指定保護需求會影響通道的建置方式,但通道開發人員並不知道這些需求。使用
Validate方法來檢查描述樹和相應的運行時物件,以確保它符合一組準則。使用
ApplyDispatchBehavior和ApplyClientBehavior方法來檢查描述樹狀結構,並在服務或客戶端上修改特定範圍的運行時環境。 您也可以插入擴充物件。備註
儘管這些方法中提供了描述樹,但它僅供審查。 如果修改描述樹狀結構,則行為可能不確定。
您可以修改的屬性,以及您可以實作的自定義介面,可透過服務和用戶端運行時間類別來存取。 服務類型是 DispatchRuntime 和 DispatchOperation 類別。 用戶端類型是 ClientRuntime 和 ClientOperation 類別。 ClientRuntime和 DispatchRuntime 類別是擴充性進入點,分別存取整個客戶端和服務範圍的運行時間屬性和延伸模組集合。 同樣地, ClientOperation 和 DispatchOperation 類別會分別公開用戶端作業和服務作業運行時間屬性和延伸模組集合。 不過,您可以從作業運行時間物件存取範圍較廣的運行時間物件,如果需要的話,反之亦然。
大部分的 WCF 使用者不會直接與運行時間互動;相反地,它們會使用核心程序設計模型建構,例如端點、合約、系結、位址,以及組態檔中的類別或行為屬性。 這些建構構成 描述樹狀結構,這是建構運行時間以支援描述樹狀結構所描述之服務或用戶端的完整規格。
WCF 中有四種行為:
服務行為(IServiceBehavior 類型)可自訂整個服務運行時間,包括 ServiceHostBase。
端點行為(IEndpointBehavior 類型)可自定義服務端點及其相關聯的 EndpointDispatcher 物件。
合約行為(IContractBehavior 類型)可分別在用戶端和服務應用程式中自定義 ClientRuntime 和 DispatchRuntime 類別。
作業行為(IOperationBehavior 類型)可再次在客戶端和服務上自定義 ClientOperation 和 DispatchOperation 類別。
您可以藉由實作自定義屬性、使用應用程式組態檔,或直接將這些行為新增至適當描述對象上的行為集合,將這些行為新增至各種描述物件。 不過,必須在ICommunicationObject.Open或ServiceHost上呼叫ChannelFactory<TChannel>之前,將其新增至服務描述或服務端點描述物件。
行為範圍
有四種行為類型,分別對應至特定運行時間存取範圍。
服務行為
服務行為,這些服務行為實作 IServiceBehavior,是修改整個服務執行環境的主要機制。 將服務行為新增至服務有三種機制。
在服務類別上使用屬性。 ServiceHost建構時,ServiceHost實作使用反射來探索服務類型的屬性集。 如果其中任一屬性是 的 IServiceBehavior實作,它們就會加入至 上 ServiceDescription的行為集合。 這使得這些行為能參與服務執行時的建構。
以程式方式將行為加入至ServiceDescription上的行為集合。 這可以使用下列幾行程式代碼來完成:
ServiceHost host = new ServiceHost(/* Parameters */); host.Description.Behaviors.Add(/* Service Behavior */);實作自定義 BehaviorExtensionElement 來擴展組態。 這可讓您從應用程式組態檔使用服務行為。
WCF 中的服務行為範例包括 ServiceBehaviorAttribute 屬性、 ServiceThrottlingBehavior、 和 ServiceMetadataBehavior 行為。
合約行為
實作 介面的 IContractBehavior 合約行為可用來跨合約擴充客戶端和服務運行時間。
將合約行為新增至合約有兩種機制。 第一個機制是建立自定義屬性,以用於合約介面。 當合約介面傳遞至 ServiceHost 或 ChannelFactory<TChannel>時,WCF 會檢查介面上的屬性。 如果有任何屬性是 的 IContractBehavior實作,這些屬性會加入至針對該介面建立的行為集合 System.ServiceModel.Description.ContractDescription 。
您也可以在自訂合約行為屬性上實施System.ServiceModel.Description.IContractBehaviorAttribute。 在此情況下,當套用至某物時,其行為如下:
•合約介面。 在這種情況下,該行為會套用至任何端點中的所有此類型合約,WCF 會忽略 IContractBehaviorAttribute.TargetContract 屬性值。
•服務階層。 在此情況下,行為僅套用至合約中的端點,其合約是由 TargetContract 屬性的值決定的。
•回呼類別。 在此情況下,行為會套用至雙工用戶端的端點,而 WCF 會忽略 屬性的值 TargetContract 。
第二個機制是將行為新增至ContractDescription的行為集合中。
WCF 中合約行為的範例包括 System.ServiceModel.DeliveryRequirementsAttribute 屬性。 如需詳細資訊和範例,請參閱參考主題。
端點行為
端點行為(endpoint IEndpointBehaviorbehaviors)是修改整個服務或用戶端執行時以符合特定端點的主要機制。
將端點行為新增至服務有兩種機制。
將行為新增至 Behaviors 屬性。
實作擴充組態的自定義 BehaviorExtensionElement 。
如需詳細資訊和範例,請參閱參考主題。
作業行為
實作 介面的 IOperationBehavior 作業行為可用來擴充每個作業的客戶端和服務運行時間。
有兩種機制可以將操作行為新增到作業中。 第一個機制是建立自定義屬性,以用於建立作業模型的方法。 將作業新增至 ServiceHost 或 ChannelFactory時,WCF 會將任何 IOperationBehavior 屬性加入至為該作業所建立的行為集合 OperationDescription 。
第二個機制是將行為直接加入到建構的OperationDescription之行為集合中。
WCF 中的作業行為範例包括 OperationBehaviorAttribute 和 TransactionFlowAttribute。
如需詳細資訊和範例,請參閱參考主題。
使用組態建立行為
服務與端點和合約行為可以設計為在程式碼中指定或使用屬性;只能使用應用程式或 Web 組態檔來設定服務和端點行為。 利用屬性暴露行為,讓開發者能在編譯時指定一個行為,該行為在執行時無法新增、移除或修改。 此常用於服務正確運作時必須具備的行為(例如,System.ServiceModel.ServiceBehaviorAttribute 屬性的交易相關參數)。 使用組態公開行為可讓開發人員將這些行為的規格和設定留給部署服務的人員。 這適用於選擇性元件或其他部署特定組態的行為,例如元數據是公開給服務還是服務的特定授權組態。
備註
您也可以使用支援設定的功能行為,將它們插入 machine.config 組態檔,並鎖定這些項目,以強制執行公司的應用程式政策。 如需描述和範例,請參閱 如何:鎖定企業中的端點。
若要使用組態公開行為,開發人員必須建立 的 BehaviorExtensionElement 衍生類別,然後使用組態註冊該延伸模組。
下列程式代碼範例示範 如何 IEndpointBehavior 實作 BehaviorExtensionElement:
// BehaviorExtensionElement members
public override Type BehaviorType
{
get { return typeof(EndpointBehaviorMessageInspector); }
}
protected override object CreateBehavior()
{
return new EndpointBehaviorMessageInspector();
}
為了讓組態系統載入自定義 BehaviorExtensionElement,它必須註冊為延伸模組。 下列程式代碼範例顯示上述端點行為的組態檔:
<configuration>
<system.serviceModel>
<services>
<service
name="Microsoft.WCF.Documentation.SampleService"
behaviorConfiguration="metadataSupport"
>
<host>
<baseAddresses>
<add baseAddress="http://localhost:8080/ServiceMetadata" />
</baseAddresses>
</host>
<endpoint
address="/SampleService"
binding="wsHttpBinding"
behaviorConfiguration="withMessageInspector"
contract="Microsoft.WCF.Documentation.ISampleService"
/>
<endpoint
address="mex"
binding="mexHttpBinding"
contract="IMetadataExchange"
/>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="metadataSupport">
<serviceMetadata httpGetEnabled="true" httpGetUrl=""/>
</behavior>
</serviceBehaviors>
<endpointBehaviors>
<behavior name="withMessageInspector">
<endpointMessageInspector />
</behavior>
</endpointBehaviors>
</behaviors>
<extensions>
<behaviorExtensions>
<add
name="endpointMessageInspector"
type="Microsoft.WCF.Documentation.EndpointBehaviorMessageInspector, HostApplication, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null"
/>
</behaviorExtensions>
</extensions>
</system.serviceModel>
</configuration>
其中 Microsoft.WCF.Documentation.EndpointBehaviorMessageInspector 是行為延伸類型,而 HostApplication 是編譯該類別的元件名稱。
評估順序
System.ServiceModel.ChannelFactory<TChannel>和 System.ServiceModel.ServiceHost 負責從程序設計模型和描述建置運行時間。 如先前所述,行為會參與服務、端點、合約和作業的建置程序。
ServiceHost 依下列順序套用行為:
服務
合約
端點
行動
在任何行為模式的集合中,無法保證存在任何特定順序。
ChannelFactory<TChannel> 依下列順序套用行為:
合約
端點
行動
同樣地,在任何行為集合中,不保證任何順序。
以程序設計方式新增行為
在服務應用程式中的System.ServiceModel.Description.ServiceDescription屬性,在CommunicationObject.OnOpening上的System.ServiceModel.ServiceHostBase方法之後,不得被修改。 某些成員,例如 ServiceHostBase.Credentials 屬性和 AddServiceEndpointServiceHostBase 上的 System.ServiceModel.ServiceHost 方法,如果修改超過該點,則會拋出例外狀況。 其他人則允許您修改它們,但結果未定義。
同樣地,在用戶端上,在對System.ServiceModel.Description.ServiceEndpoint呼叫OnOpening之後,不得修改System.ServiceModel.ChannelFactory的值。 ChannelFactory.Credentials屬性會在修改超過該點時擲回例外狀況,但其他用戶端描述值可以修改而不會發生錯誤。 不過,結果未定義。
無論是針對服務還是客戶端,建議您先修改描述,再呼叫 CommunicationObject.Open。
行為屬性的繼承規則
這四種行為都可以使用屬性來填入 – 服務行為和合約行為。 因為屬性是在 Managed 對象和成員上定義,而 Managed 物件和成員支援繼承,所以必須定義行為屬性在繼承內容中的運作方式。
概括而言,規則是針對特定範圍(例如服務、合約或作業),該範圍繼承階層中的所有行為屬性都會套用。 如果相同類型有兩個行為屬性,則只會使用最衍生的類型。
服務行為
針對指定的服務類別,該類別及其父類別的所有服務行為屬性都會被套用。 如果在繼承階層的多個位置套用相同類型的屬性,則會使用衍生最多的類型。
[ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Multiple)]
[AspNetCompatibilityRequirementsAttribute(
AspNetCompatibilityRequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
public class A { /* … */ }
[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]
public class B : A { /* … */}
例如,在上述案例中,服務 B 最後會有 InstanceContextMode 的 Single、AspNetCompatibilityRequirementsMode 模式為 Allowed,以及 ConcurrencyMode 的 Single。 ConcurrencyMode是 Single,因為ServiceBehaviorAttribute服務 B 上的屬性比服務 A 上的屬性「衍生得更多」。
合約行為
針對指定的合約,會套用該介面及其父介面上的所有合約行為屬性。 如果在繼承階層的多個位置套用相同類型的屬性,則會使用衍生最多的類型。
作業行為
如果指定的作業未覆寫現有的抽象或虛擬作業,則不會套用繼承規則。
如果某個作業取代了現有的作業,則該作業以及其父代上的所有作業行為屬性都會被套用。 如果在繼承階層的多個位置套用相同類型的屬性,則會使用衍生最多的類型。