WCF使用Header如何正確實(shí)現(xiàn)
對(duì)于一個(gè)經(jīng)驗(yàn)豐富的編程人員來(lái)說(shuō),它不可能不知道WCF為何物。作為一個(gè).NET Framework 3.5的重要組成部件,為我們帶來(lái)了非常大的好處。我們?cè)谶@里先來(lái)了解一下WCF使用Header的相關(guān)應(yīng)用技巧。
在WCF中如何實(shí)現(xiàn)登陸,典型的場(chǎng)景如下:
- [ServiceContract]
- public interface ILogin {
- [OperationContract]
- bool Signin(string userName, string password);
- }
- [ServiceContract]
- public interface IBizTest {
- [OperationContract]
- string GetWelcomeInfo();
- }
千萬(wàn)別從WCF自帶的那個(gè)InstanceContextMode來(lái)想辦法,因?yàn)閃CF中的PerSession調(diào)用只是針對(duì)每個(gè)服務(wù)類而言的,除非你變態(tài)到服務(wù)端只有一個(gè)類來(lái)實(shí)現(xiàn)全部的接口;#t#
變個(gè)思路,能不能用類似.NET Remoting中的CallContext呢?但是查了一下WCF的手冊(cè),好像也沒有這么個(gè)東西,怎么解決呢?那就是Custom header.
解決方案提出前,需要知道一點(diǎn)的就是,服務(wù)端取客戶端送出的Header的方法:
先遍歷OperationContext.Current.IncomingMessageHeaders找出客戶端發(fā)送的Header Name,然后再用 OperationContext.Current.IncomingMessageHeaders.GetHeader<T>(i)得到值就可以啦。
下面的問(wèn)題就剩下客戶端怎么發(fā)送Custom Header了。
策略1:在每個(gè)客戶端Proxy中增加類似如下的代碼
- using (OperationContextScope scope = new
OperationContextScope(InnerChannel)) {- MessageHeader mh = MessageHeader.CreateHeader("HeaderName",
string.Empty, "HeaderValue");- OperationContext.Current.OutgoingMessageHeaders.Add(mh);
- //…
- }
但是每個(gè)客戶端都要增加,這樣的WCF使用Header的步驟太麻煩了,所以,引出
2.自定義一個(gè)CallContextAttribute,代碼如下:
1. 先定義一個(gè)IClientMessageInspector接口的實(shí)現(xiàn)類
- public class ContextHeader : IClientMessageInspector {
- public void AfterReceiveReply(ref System.ServiceModel.
Channels.Message reply, object correlationState) {- //
- }
- public object BeforeSendRequest(ref System.ServiceModel.
Channels.Message request, IClientChannel channel) {- MessageHeader clientHeader = MessageHeader.CreateHeader
("headerName", string.Empty, "headerValue");- request.Headers.Add(clientHeader);
- return null;
- }
- }
OK , 然后就可以實(shí)現(xiàn)CallContextAttribute了
- public class CallContextAttribute : Attribute, IEndpointBehavior,
IOperationBehavior {- IEndpointBehavior Members#region IEndpointBehavior Members
- public void AddBindingParameters(ServiceEndpoint endpoint,
BindingParameterCollection bindingParameters) {- }
- public void ApplyClientBehavior(ServiceEndpoint endpoint,
ClientRuntime clientRuntime) {- clientRuntime.MessageInspectors.Add(new ContextHeader());
- }
- public void ApplyDispatchBehavior(ServiceEndpoint endpoint,
EndpointDispatcher endpointDispatcher) {- }
- public void Validate(ServiceEndpoint endpoint) {
- }
- #endregion
- IOperationBehavior Members#region IOperationBehavior Members
- public void AddBindingParameters(OperationDescription operationDescription,
BindingParameterCollection bindingParameters) {- }
- public void ApplyClientBehavior(OperationDescription operationDescription,
ClientOperation clientOperation) {- clientOperation.Parent.MessageInspectors.Add(new ContextHeader ());
- }
- public void ApplyDispatchBehavior(OperationDescription operationDescription,
DispatchOperation dispatchOperation) {- }
- public void Validate(OperationDescription operationDescription) {
- }
- #endregion
- }
完工大吉,***在我們Contract中加入CallContextAttribute就可以啦,客戶端不用增加任何代碼了。
- [ServiceContract]
- [CallContext]
- public interface IBizTest {
- [OperationContract]
- [CallContext]
- string GetWelcomeInfo();
- }
以上就是我們?yōu)榇蠹医榻B的WCF使用Header的相關(guān)操作方法。