如何在WCF中使用自定义的Header,(典型场景:业务系统的登陆与使用)

  问题提出:

WCF中如何实现登陆,典型的场景如下:

[ServiceContract]

public interface ILogin {

        [OperationContract]

        
bool Signin(string userName, string password);

}


[ServiceContract]

public interface IBizTest {

        [OperationContract]

        
string GetWelcomeInfo();

}


千万别从WCF自带的那个InstanceContextMode来想办法,因为WCF中的PerSession调用只是针对每个服务类而言的,除非你变态到服务端只有一个类来实现全部的接口;

变个思路,能不能用类似.NET Remoting中的CallContext呢?但是查了一下WCF的手册,好像也没有这么个东西,怎么解决呢?那就是Custom header.

解决方案提出前,需要知道一点的就是,服务端取客户端送出的Header的方法:

先遍历OperationContext.Current.IncomingMessageHeaders找出客户端发送的Header Name,然后再用 OperationContext.Current.IncomingMessageHeaders.GetHeader<T>(i)得到值就可以啦。

下面的问题就剩下客户端怎么发送Custom Header了。
策略1:在每个客户端Proxy中增加类似如下的代码

using (OperationContextScope scope = new OperationContextScope(InnerChannel)) {

                MessageHeader mh 
= MessageHeader.CreateHeader("HeaderName"string.Empty, "HeaderValue");

                OperationContext.Current.OutgoingMessageHeaders.Add(mh);

                
//

 }

 

但是每个客户端都要增加,太麻烦了,所以,引出

2.
自定义一个CallContextAttribute,代码如下:

1. 先定义一个IClientMessageInspector接口的实现类

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 , 然后就可以实现CallContextAttribute

public class CallContextAttribute : Attribute, IEndpointBehavior, IOperationBehavior {

IEndpointBehavior Members

IOperationBehavior Members

}



完工大吉,最后在我们Contract中加入CallContextAttribute就可以啦,客户端不用增加任何代码了。

[ServiceContract]

[CallContext]

public interface IBizTest {

        [OperationContract]

[CallContext]

        
string GetWelcomeInfo();

}


posted @ 2008-01-11 00:06  billqian  阅读(2312)  评论(4编辑  收藏  举报