当前位置:编程学习 > asp >>

WCF4.0进阶系列第十一章 编写代码控制配置和通信(中)

 

 

摘要

WCF服务的分发器可以在把消息传递至服务实例的方法之前或在接收到服务的响应消息之后,翻译并检查这些消息。如果你需要实现消息检查功能,那么你首先需要自定义检查消息的服务行为,然后通过硬编码将服务行为嵌入到代码中或扩展WCF服务行为并通过配置文件配置消息检查功能。

检查消息

WCF服务模型的一个有趣的特性是分发消息至服务的方法之前翻译消息,在离开服务方法后进入向客户端回传的传从通道堆栈之前再次翻译消息。采用消息翻译,可以在接收和发送消息的时候检查消息。你还可以在服务实例对象的方法处理消息之前或向客户端发送响应消息之前修改消息。尽管你在使用它时必须小心地处理以避免为你的系统带来安全方面的隐患或漏洞,消息检查仍然是一项非常有用的技术。

你可以创建一个消息检查器来翻译消息;即创建一个实现IDispatchMessageInspector接口的类,然后定义一个行为把该对象插入到WCF基础架构中;该行为决定了消息翻译的范围。如果你指定消息翻译为一个服务行为,那么所有发送至服务的消息都将被翻译。你还可以指定消息翻译为一个操作行为,端点行为或者合约行为;相应地,经过操作、端点和合约的消息都将被翻译。

你可以在客户端程序或者服务中实现消息检查。在下面的练习中,你将看到如何创建并集成一个消息检查器至服务端的WCF运行时的分发机制中。如果服务接收到消息,消息检查器将显示接收到的消息。如果你想在客户端检查消息,那么需要实现IClientMessageInspector接口。

为ShippingCartService服务创建消息检查器

1. 在Visual Studio的解决方案窗口中,选择ShoppingCartService项目。在项目菜单中,选择添加一个新的类文件,并命名为ShoppingCartInspector.cs

2. 在ShoppingCartInspector.cs文件中,添加下面的语句

1usingSystem.ServiceModel.Dispatcher;
2usingSystem.ServiceModel.Description;

3. 修改ShoppingCartInspector类的定义,使其实现IDispatchMessageInspector接口

1publicclassShoppingCartInspector : IDispatchMessageInspector
2{
3}

IDispatchMessageInspector接口定义两个方法,使用这两个方法你可以查看和修改进入和离开服务的消息。
4. 在IDispatchMessageInspector上面点击右键,指向实现接口à实现接口。Visual Studio自动生成IDispatchMessageInspector接口的两个方法。一个名为AfterReceiveRequest,在服务的方法被访问之前调用该方法;另外一个为BeforeSendReply,在服务的方法结束之前调用该方法。请注意两个方法的第一个参数都是Message对象类型。该参数的值为刚刚收到或者即将发出的消息对象。你在方法里可以修改该消息对象的内容,你对该对象所作的改动都将传递至服务或者返回到客户端,这取决于该消息是客户端发送的请求消息还是服务的响应消息。由于这个原因,你在修改消息时应格外小心,不要做了相反的修改。
5. 修改Visual Studio生成的AfterReceiveRequest方法的内容

1publicobjectAfterReceiveRequest(refSystem.ServiceModel.Channels.Message request,
2    System.ServiceModel.IClientChannel channel, System.ServiceModel.InstanceContext instanceContext)
3{
4    Console.WriteLine("Message received: {0}\n{1}\n\n", request.Headers.Action, request.ToString());
5    returnnull;
6}

第一行代码显示消息的行为和消息的内容。在某些情况下,关联AfterReceiveRequest方法的消息和BeforeSendReply方法的消息是非常有用的。如果你查看BeforeSendReply方法,你可以看到该方法的第二个参数为correlationState。如果你需要关联请求和响应消息,你可以在AfterReveiveRequest方法中创建一个唯一的标识符并返回改值。WCF运行时将把相同的标识符作为参数传递至方法BeforeSendReplyMethod。在当前的练习中,你没有关联任何请求和回复消息,所以AfterReceiveRequest方法将返回null。

6. 修改Visual Studio生成的BeforeSendReply方法的内容

1publicvoidBeforeSendReply(refSystem.ServiceModel.Channels.Message reply, objectcorrelationState)
2{
3    Console.WriteLine("Message sent: {0}\n{1}\n\n", reply.Headers.Action, reply.ToString());
4}

7. 重新生成ShoppingCartService方案

创建自定义行为

使用服务行为,你可以把ShoppingCartInspector实现的行为集成到WCF运行时。然而WCF并未提供内建的"IntegrateShoppingCartInspector"服务行为。幸运的是,创建一个实现IServieBehavior接口的类以实现集成服务行为,这并不难。

IServiceBehavor接口定义了三个方法,其实现类必须实现这三个方法,才可能在WCF基础架构中扮演服务行为。这三个方法如下:

  • AddingBindingParameters,一些行为可以接收额外的数据项作为参数,并传递至绑定元素,管理员或者开发人员可以在BindingParameterCollection中提供这些信息并将这些信息传递至该方法。WCF运行时针对服务侦听的每个URI都调用一次AddingBindingParameters方法。
  • ApplyDispatcherBehavior, 使用该方法,你可以修改ServiceHost对象所寄宿服务的行为。ServiceHost对象被作为该方法的第二个参数传入。使用该方法可以执行的任务包括添加自定义错误处理,或者消息检查对象。
  • Validate,WCF运行时调用该方法以验证服务是否满足你自己定义的需求。比如,你可以检查该方法的第一个参数(传入的服务描述对象),如果该服务的合约与期望的不一致,你可以拒绝并抛出一个异常。

如果你需要实现一个操作行为、服务端点行为、或者合约行为,那么你需要实现IOperationBehavior、IEndpointBehavior和IContractBehavior接口。这些接口与IServiceBehavior非常相似。他们都对外暴露AddingBindingParameters、ApplyDispatcherBehavior和Validate方法,尽管这些方法接收的参数不同(因为这些接口的范围分别指向操作,服务端点和合约),但是它们的目的都一样。此外,这三个接口提供了一个名为ApplyClientBehavior的方法。这个方法接收一个名为ClientRuntime的参数,该参数为客户端WCF运行时对象。你可以修改该对象的属性以配置客户端运行时的运行方式;在需要检查或者管理客户端发送和接口的消息时,你还可以插入一个消息检查器至客户端运行时。

在下面的练习中,你将实现一个IServiceBehavir接口,并创建一个可以用以添加消息检查器服务行为至ShoppingCartService服务

为ShoppingCartService服务创建一个服务行为

1. 在文件ShoppingCartInspector.cs中,添加一个名为ShoppingCartBehavior的public类,该类实现IServiceBehavior接口

publicclassShoppingCartBehavior : IServiceBehavior

2. 在IServiceBehavior上点击右键,指向实现接口à实现接口。Visual Studio将自动生成AddBindingParameters、ApplyDispatcherBehavior和Validate方法

3. 注释掉AddingBindingParameters和Validate方法内的throw语句。


4. 修改ApplyDispatcherBehavior方法

 1publicvoidApplyDispatchBehavior(ServiceDescription serviceDescription,
 2    System.ServiceModel.ServiceHostBase serviceHostBase)
 3{
 4    foreach(ChannelDispatcher channelDispatcher inserviceHostBase.ChannelDispatchers)
 5    {
 6        foreach(EndpointDispatcher endpointDispatcher inchannelDispatcher.Endpoints)
 7        {
 8            endpointDispatcher.DispatchRuntime.MessageInspectors.Add(newShoppingCartInspector());
 9        }
10    }
11}

上都代码首先迭代ChannelDispatchers;然后再迭代每个ChannelDispatcher的EndpointDispatcher;然后添加ShoppingCartInspector对象到每个EndpointDispatcher上。随后,当一个EndpointDispatcher对象分发一个服务方法或者一个服务方法返回到EndpointDispatcher对象,消息都将通过ShoppingCartInspector对象传输。

5. 打开Programm.cs文件,修改main方法中,以使ShoppingCartService运行时,添加ShoppingCartServiceBehavior实现的服务行为

 1st

补充:Web开发 , ASP.Net ,
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,