十五天精通WCF——第九天 高级玩法之自定义Behavior

一: Behavior这个泼妇的厉害

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

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



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

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

二:端点级别Behavior

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

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

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

1. IDispatchMessageInspector

public class MyDispatchMessageInspector : IDispatchMessageInspector
 {
 public object AfterReceiveRequest(ref Message request, IClientChannel channel, InstanceContext instanceContext)
 {
 Console.WriteLine(request.ToString());
 return request;
 }

 public void BeforeSendReply(ref Message reply, object correlationState)
 {
 Console.WriteLine(reply.ToString());
 }
 }

2. IEndpointBehavior

public class MyEndpointBehavior : IEndpointBehavior
 {
 public void AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters)
 {
 }

 public void ApplyClientBehavior(ServiceEndpoint endpoint, System.ServiceModel.Dispatcher.ClientRuntime clientRuntime)
 {
 }

 public void ApplyDispatchBehavior(ServiceEndpoint endpoint, System.ServiceModel.Dispatcher.EndpointDispatcher endpointDispatcher)
 {
 endpointDispatcher.DispatchRuntime.MessageInspectors.Add(new MyDispatchMessageInspector());
 }

 public void Validate(ServiceEndpoint endpoint)
 {
 }
 }

3. 将MyEndpointBehavior加入到Host中

static void Main(string[] args)
 {
 ServiceHost host = new ServiceHost(typeof(HomeService), new Uri("http://127.0.0.1:1920"));

 host.AddServiceEndpoint(typeof(IHomeService), new BasicHttpBinding(), "HomeServie");

 host.Description.Behaviors.Add(new ServiceMetadataBehavior() { HttpGetEnabled = true });

 host.AddServiceEndpoint(typeof(IMetadataExchange), MetadataExchangeBindings.CreateMexHttpBinding(), "mex");

 host.Description.Endpoints[0].EndpointBehaviors.Add(new MyEndpointBehavior());

 host.Open();

 Console.WriteLine("服务已经开启!!!");

 Console.Read();
 }

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

public class HomeService : IHomeService
 {
 public string Update(string message)
 {
 Console.WriteLine("我在Action方法:" + message);

 return "my reply!!!";
 }
 }

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


三:操作级别Behavior

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

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

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

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

<1> IParameterInspector 的玩法

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

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

1. IParameterInspector

public class MyIParameterInspector : IParameterInspector
 {
 public int MaxLength { get; set; }

 public MyIParameterInspector(int MaxLength)
 {
 this.MaxLength = MaxLength;
 }

 /// <summary>
 /// 出站的操作
 /// </summary>
 /// <param name="operationName"></param>
 /// <param name="outputs"></param>
 /// <param name="returnValue"></param>
 /// <param name="correlationState"></param>
 public void AfterCall(string operationName, object[] outputs, object returnValue, object correlationState)
 {

 }

 /// <summary>
 /// 入站的参数
 /// </summary>
 /// <param name="operationName"></param>
 /// <param name="inputs"></param>
 /// <returns></returns>
 public object BeforeCall(string operationName, object[] inputs)
 {
 foreach (var item in inputs)
 {
 if (Convert.ToString(item).Length > MaxLength)
 {
 throw new Exception("码单,长度不能超过 " + MaxLength + " 个长度");
 }
 }

 return null;
 }
 }

2. IOperationBehavior

public class MyOperationBehavior : Attribute, IOperationBehavior
 {
 public int MaxLength { get; set; }

 public void AddBindingParameters(OperationDescription operationDescription, BindingParameterCollection bindingParameters)
 {

 }

 public void ApplyClientBehavior(OperationDescription operationDescription, ClientOperation clientOperation)
 {

 }

 public void ApplyDispatchBehavior(OperationDescription operationDescription, DispatchOperation dispatchOperation)
 {
 dispatchOperation.ParameterInspectors.Add(new MyIParameterInspector(MaxLength));
 }

 public void Validate(OperationDescription operationDescription)
 {

 }
 }

3. 在Action在加上MyOperationBehavior 这个 Attribute

public class HomeService : IHomeService
 {
 [MyOperationBehavior(MaxLength = 5)]
 public string Update(string message)
 {
 Console.WriteLine("我在Action方法:" + message);

 return "my reply!!!";
 }
 }

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

public class Program1
 {
 static void Main(string[] args)
 {
 HomeServiceClient client = new HomeServiceClient();

 client.Update("我故意输入了很多的字符,哈哈。。。。。");

 Console.Read();
 }
 }

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


<2> MessageFormatter,IOperationInvoker 的玩法

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

时间: 2024-10-30 23:34:14

十五天精通WCF——第九天 高级玩法之自定义Behavior的相关文章

十五天精通WCF——第十天 学会用SvcConfigEditor来简化配置

原文:十五天精通WCF--第十天 学会用SvcConfigEditor来简化配置        我们在玩wcf项目的时候,都是自己手工编写system.serviceModel下面的配置,虽然在webconfig中做wcf的服务配置的时候,vs提供大多 数的代码提示,但对于不太熟悉服务配置的小鸟们来说,有些困难,而且一些服务配置也容易遗漏,大多情况下,我们都是copy一份服务配置,然 后在服务配置上面修修改改,对吧...其实呢,.net给我们提供了一个强大的scvconfigeditor这个工具

十五天精通WCF——第八天 对“绑定”的最后一点理解

原文:十五天精通WCF--第八天 对"绑定"的最后一点理解 转眼已经中断10几天没有写博客了,也不是工作太忙,正好碰到了端午节,然后最近看天津台的爱情保卫战入迷了...太好看了,一直都是回味无穷...而且 涂磊老师话说的真是tmd的经典,然后就这样耽搁了,好了,话不多说,这篇我们看看binding中最后一点需要知道的东西.   一:信道栈 我在之前的文章中多次提到信道栈,不知道大家对它的概念是否有了解,其实想想也还是蛮简单的,既然是栈,那么这个栈肯定就不止一个元素了,对吧,第二个 的话

十五天精通WCF——第三天 client如何知道server提供的功能清单

原文:十五天精通WCF--第三天 client如何知道server提供的功能清单  通常我们去大保健的时候,都会找姑娘问一下这里能提供什么服务,什么价格,这时候可能姑娘会跟你口述一些服务或者提供一份服务清单,这样的话大 家就可以做到童嫂无欺,这样一份活生生的例子,在wcf中同样是一个道理,只有client了解service能提供哪些功能,client才可以根据server提供的功能进行 消费,那问题来了,service怎么把功能提供给client进行选择呢???这个就是我这一篇要聊的wsdl(w

十五天精通WCF——第二天 告别烦恼的config配置

原文:十五天精通WCF--第二天 告别烦恼的config配置   经常搞wcf的基友们肯定会知道,当你的应用程序有很多的"服务引用"的时候,是不是有一种疯狂的感觉...从一个环境迁移到另外一个环境,你需要改变的 endpoint会超级tmd的多,简直就是搞死了人...好了,这篇我们来看看如何最小化配置.   一:精简service的config配置 就像上一篇的代码一样,我的service端的config配置如下: 1 <?xml version="1.0"

十五天精通WCF——第十二天 说说wcf中的那几种序列化

原文:十五天精通WCF--第十二天 说说wcf中的那几种序列化 我们都知道wcf是由信道栈组成的,在我们传输的参数走到传输信道层之前,先需要经过序列化的过程,也就是将参数序列化为message,这篇 我们就来说说这里的序列化,蛮有意思的,可能初学者也明白,在wcf中默认的序列化是DataContractSerializer,确实是这样,不过wcf在信道中 其实不仅仅支持DataContractSerializer,它还支持其他类型的序列化,比如XmlSerializer,NetDataContr

十五天精通WCF——第十一天 如何对wcf进行全程监控

说点题外话,我们在玩asp.net的时候,都知道有一个叼毛玩意叫做"生命周期",我们可以用httpmodule在先于页面的page_load中 做一些拦截,这样做的好处有很多,比如记录日志,参数过滤,全局登录验证等等...在wcf里面的话也是有类似的功能,第一种就是在 endpoint中加上runtime的behavior,这样的话就可以先于"服务方法"做拦截,第二种方法呢,也就是我们这一篇所说的全程监控,俗称 "诊断功能".   一:诊断 我也

十五天精通WCF——第一天 三种Binding让你KO80%的业务

转眼wcf技术已经出现很多年了,也在.net界混的风生水起,同时.net也是一个高度封装的框架,作为在wcf食物链最顶端的我们所能做的任务已经简单的不能再简单了, 再简单的话马路上的大妈也能写wcf了,好了,wcf最基本的概念我们放在后面慢慢分析,下面我们来看看神奇的3个binding如何KO我们实际场景中的80%的业务场景. 一:basicHttpBinding 作为入门第一篇,也就不深入谈谈basic中的信道栈中那些啥东西了,你只需要知道有ABC三个要素,注意不是姨妈巾哦,如果需要详细了解,

十五天精通WCF——第十四天 一起聊聊FaultException

 我们在玩web编程的时候,可能你会不经意的见到一些http500的错误,我想你应该不会陌生的,原因你应该也知道,服务器异常嘛, 这时候clr会把这个未处理的异常抛给iis并且包装成http500的错误返回到客户端,就比如下面这样.     从这张图中,我故意输入了xss字符,然后的然后,web程序自爆异常,其实我想表达的意思就是,虽然说web程序抛异常了,但不代表iis就 挂了,所以iis还是需要给客户端做出反馈,这就有了http header,和body信息,同样的道理,wcf的服务器异常机

十五天精通WCF——终结篇 那些你需要注意的坑

终于一路走来,到了本系列的最后一篇了,这一篇也没什么好说的,整体知识框架已经在前面的系列文章中讲完了,wcf的配置众多,如果 不加一些指定配置,你可能会遇到一些灾难性的后果,快来一睹为快吧. 一: 第一个大坑 [数据传输量] 我们使用wcf的目的,就是用来进行分布式的数据交互,既然是交互,就一定要进行数据交换,可能一些新人并没有注意到wcf在数据传输量上 面做了一个大小限制,比如我现在要传输一个2m的txt给service,会出现什么情况??? static void Main(string[]