为了账号安全,请及时绑定邮箱和手机立即绑定

高级玩法之自定义Behavior

标签:
资讯

 

  终于我又看完了二期爱情保卫战,太酸爽了,推荐链接:http://www.iqiyi.com/a_19rrgublqh.html?vfm=2008_aldbd,不多说,谁看谁入迷,下面言归正传,

看看这个很有意思的Behavior。

 

一: Behavior这个泼妇的厉害

    在前面的文章中,我也清楚的说明了整个wcf通信流,而Behavior这个泼妇可以在wcf通信流中的任何地方插上一脚,蛮狠无比,利用的好,让你上天堂,利用的不

好,让你下地狱。。。下面让你看看behavior到底有哪些可以注入的点???先画个简图:

上面的图,大概就是wcf的通信简图,所有蓝色字体都是Behavior注入的点,其中Client和Service端都可以注入,如果按照功能分的话,又可以分为“操作级别”和

”端点级别“,下面我来简要的分解下。

 

二:端点级别Behavior

  从图中你也可以看到,消息检查器是放在Channel这个级别的,也就是说它可以监视Client和Server的入站请求,也就是说所有的请求都需要通过它转发,如果

这样的话,那我是不是可以在这个注入点上自由的修改,变更,拦截入站和出站请求,而且利用这个特性我还可以做很多的事情,比如日志记录,记录统计等等,下

面我们来看看这个怎么使用??? 只需要extends IEndpointBehavior  和 IDispatchMessageInspector,然后加入EndpointBehaviors即可。。。

 1. IDispatchMessageInspector

复制代码

 1     public class MyDispatchMessageInspector : IDispatchMessageInspector 2     { 3         public object AfterReceiveRequest(ref Message request, IClientChannel channel, InstanceContext instanceContext) 4         { 5             Console.WriteLine(request.ToString()); 6             return request; 7         } 8  9         public void BeforeSendReply(ref Message reply, object correlationState)10         {11             Console.WriteLine(reply.ToString());12         }13     }

复制代码

2. IEndpointBehavior

复制代码

 1     public class MyEndpointBehavior : IEndpointBehavior 2     { 3         public void AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters) 4         { 5         } 6  7         public void ApplyClientBehavior(ServiceEndpoint endpoint, System.ServiceModel.Dispatcher.ClientRuntime clientRuntime) 8         { 9         }10 11         public void ApplyDispatchBehavior(ServiceEndpoint endpoint, System.ServiceModel.Dispatcher.EndpointDispatcher endpointDispatcher)12         {13             endpointDispatcher.DispatchRuntime.MessageInspectors.Add(new MyDispatchMessageInspector());14         }15 16         public void Validate(ServiceEndpoint endpoint)17         {18         }19     }

复制代码

3. 将MyEndpointBehavior加入到Host中

复制代码

 1   static void Main(string[] args) 2         { 3             ServiceHost host = new ServiceHost(typeof(HomeService), new Uri("http://127.0.0.1:1920")); 4  5             host.AddServiceEndpoint(typeof(IHomeService), new BasicHttpBinding(), "HomeServie"); 6  7             host.Description.Behaviors.Add(new ServiceMetadataBehavior() { HttpGetEnabled = true }); 8  9             host.AddServiceEndpoint(typeof(IMetadataExchange), MetadataExchangeBindings.CreateMexHttpBinding(), "mex");10 11             host.Description.Endpoints[0].EndpointBehaviors.Add(new MyEndpointBehavior());12 13             host.Open();14 15             Console.WriteLine("服务已经开启!!!");16 17             Console.Read();18         }

复制代码

4. 最后我们看一下服务方法

复制代码

1    public class HomeService : IHomeService2     {3         public string Update(string message)4         {5             Console.WriteLine("我在Action方法:" + message);6 7             return "my reply!!!";8         }9     }

复制代码

 

下面看看效果。。。在效果图中,你应该看到了。在我的Action中的方法前后各有一段“入站消息”和“出站消息”,是不是很爽???

 

三:操作级别Behavior

  从文章开头的简图中,你应该看到了,Operation级别的Behavior比较多,有“操作启动器(IOperationInvoker)","参数检查(IParameterInspector)“,

“消息格式化器(IDispatchMessageFormatter)”等等。。。 为什么说等等这个词,很简单啊,,,其实还有很多系统内置的,既然是Operation,那就必

然是针对方法的,还记得OperationContract是怎么套在方法上的吗??? 是特性,对吧,,,同样的道理,OperationBehavior也是一样,那怎么用呢??

同样也是很简单的,继承几个接口即可。。。

 <1> IParameterInspector 的玩法

   其实没什么好说的,既然是属于Operation下面的Behavior,那都是通过特性注入的,而这个IParameterInspector,可以做到类似Mvc的Model验证,下面

我做个简单的Action参数长度验证(长度不超过8个字符)。

1. IParameterInspector

复制代码

 1     public class MyIParameterInspector : IParameterInspector 2     { 3         public int MaxLength { get; set; } 4  5         public MyIParameterInspector(int MaxLength) 6         { 7             this.MaxLength = MaxLength; 8         } 9 10         /// <summary>11         /// 出站的操作12         /// </summary>13         /// <param name="operationName"></param>14         /// <param name="outputs"></param>15         /// <param name="returnValue"></param>16         /// <param name="correlationState"></param>17         public void AfterCall(string operationName, object[] outputs, object returnValue, object correlationState)18         {19 20         }21 22         /// <summary>23         /// 入站的参数24         /// </summary>25         /// <param name="operationName"></param>26         /// <param name="inputs"></param>27         /// <returns></returns>28         public object BeforeCall(string operationName, object[] inputs)29         {30             foreach (var item in inputs)31             {32                 if (Convert.ToString(item).Length > MaxLength)33                 {34                     throw new Exception("码单,长度不能超过 " + MaxLength + " 个长度");35                 }36             }37 38             return null;39         }40     }

复制代码

2. IOperationBehavior

复制代码

 1 public class MyOperationBehavior : Attribute, IOperationBehavior 2     { 3         public int MaxLength { get; set; } 4  5         public void AddBindingParameters(OperationDescription operationDescription, BindingParameterCollection bindingParameters) 6         { 7  8         } 9 10         public void ApplyClientBehavior(OperationDescription operationDescription, ClientOperation clientOperation)11         {12 13         }14 15         public void ApplyDispatchBehavior(OperationDescription operationDescription, DispatchOperation dispatchOperation)16         {17             dispatchOperation.ParameterInspectors.Add(new MyIParameterInspector(MaxLength));18         }19 20         public void Validate(OperationDescription operationDescription)21         {22 23         }24     }

复制代码

3. 在Action在加上MyOperationBehavior 这个 Attribute

复制代码

 1     public class HomeService : IHomeService 2     { 3         [MyOperationBehavior(MaxLength = 5)] 4         public string Update(string message) 5         { 6             Console.WriteLine("我在Action方法:" + message); 7  8             return "my reply!!!"; 9         }10     }

复制代码

4. 然后我在客户端故意输入大于5的字符,看看效果怎么样???

复制代码

 1    public class Program1 2     { 3         static void Main(string[] args) 4         { 5             HomeServiceClient client = new HomeServiceClient(); 6  7             client.Update("我故意输入了很多的字符,哈哈。。。。。"); 8  9             Console.Read();10         }11     }

复制代码

5. 最后看看效果图,可以看到,最终的入站消息会抛出一个异常。。。

 

 

<2> MessageFormatter,IOperationInvoker 的玩法

   剩下的这两个玩法都差不多,你只需要extends一下,然后加入到OperationBehavior即可,有了上面的思想,我想下面这些使用起来都不是问题吧。。。

 

点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消