• 十五天精通WCF——第九天 高级玩法之自定义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 : IHomeService
    2     {
    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即可,有了上面的思想,我想下面这些使用起来都不是问题吧。。。

  • 相关阅读:
    windows 运行hadoop的WordCount报nativeio.NativeIO$Windows.createDirectoryWithMode0(Ljava/lang/String;I)
    java对象比较==和equals的区别
    java poi处理excel多sheet并实现排序
    hadoop-eclipse插件编译及windows下运行wordcount项目
    hadoop动态添加删除节点datanode及恢复
    hadoop的client搭建-即集群外主机访问hadoop
    appium+python,app自动化测试框架
    [adb]查看 App的appPackage和appActivity
    Django基础(二)
    JavaScript、Dom和jQuery
  • 原文地址:https://www.cnblogs.com/huangxincheng/p/4621971.html
Copyright © 2020-2023  润新知