自定义 Behavior
自定义Behavior 允许在WCF 构建运行时环境和消息处理管道的关键点上插入代码。
实现自定义行为的步骤:
1. 创建一个实现了 Inspector、Selector、Formatter、或Invoker 接口的类;
2. 创建一个实现了下列行为接口之一的类:IServiceBehavior、IEndpointBehavior、IOperationBehavior或IContractBehavior;
3. 配置客户端或服务来使用行为,可由 代码、配置文件、属性来完成;
服务端行为实现消息检验器
该Demo实现一个日志行为,输出端点发送和接收的每条消息,代码实现了从端点行为调用的一个消息检验器,以及在一个自定义扩管服务中手工的向服务描述添加端点行为。
public class MyEndpointBehavior : IEndpointBehavior{#region IEndpointBehavior Memberspublic void AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters){}public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime){}public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher){endpointDispatcher.DispatchRuntime.MessageInspectors.Add(new MyMessageInspector());}public void Validate(ServiceEndpoint endpoint){}#endregion}public class MyMessageInspector : IDispatchMessageInspector{#region IDispatchMessageInspector Memberspublic object AfterReceiveRequest(ref Message request, IClientChannel channel, InstanceContext instanceContext){Console.WriteLine(request.ToString());return request;}public void BeforeSendReply(ref Message reply, object correlationState){}#endregion}
执行结果:
结果分析:
服务端输出每次接收到的Message数据;
通过属性暴露服务操作行为的参数检验器
Demo功能说明: 使用正则表达式对参数进行校验,当参数无效时返回错误消息; 从操作行为调用参数检验器,实现属性的操作行为,在服务定义中通过属性引用将操作行为添加到服务描述中;
[AttributeUsage(AttributeTargets.Method)]public class MyOperationBehavior : Attribute, IOperationBehavior{public string Pattern;public string Message;#region IOperationBehavior Memberspublic void AddBindingParameters(OperationDescription operationDescription, BindingParameterCollection bindingParameters){}public void ApplyClientBehavior(OperationDescription operationDescription, ClientOperation clientOperation){}public void ApplyDispatchBehavior(OperationDescription operationDescription, DispatchOperation dispatchOperation){dispatchOperation.ParameterInspectors.Add(new MyParameterInspector(Pattern, Message));}public void Validate(OperationDescription operationDescription){}#endregion}public class MyParameterInspector : IParameterInspector{string pattern;string message;public MyParameterInspector(string pattern, string message){this.pattern = pattern;this.message = message;}#region IParameterInspector Memberspublic void AfterCall(string operationName, object[] outputs, object returnValue, object correlationState){}public object BeforeCall(string operationName, object[] inputs){foreach (object input in inputs){if (input != null && input.GetType().Equals(typeof(string))){Regex regex = new Regex(pattern);if (regex.IsMatch(input.ToString())){throw new FaultException(string.Format("Parameter out of range : {0} , {1}", input.ToString(), message));}}}return null;}#endregion}[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession, ConcurrencyMode = ConcurrencyMode.Multiple)]public class StockService : IStockService{ public StockService(){Console.WriteLine("{0}:Created new instance of StockService on thread", DateTime.Now);}public class Worker{public string ticker;public Update workProcess;}public static Hashtable workers = new Hashtable();public static object locker = new object();private int callsCounter = 0;#region IStockService Members[MyOperationBehavior(Pattern="[^a-zA-Z]",Message="Only alpha characters allowed")]public double GetPrice(string ticker){Console.WriteLine("{0}: GetPrice called on thread {1}", DateTime.Now, Thread.CurrentThread.ManagedThreadId); Thread.Sleep(5000);return 94.85;}public void RegisterForUpdate(string ticker){Worker worker = null;if (!workers.ContainsKey(ticker)){worker = new Worker();worker.ticker = ticker;worker.workProcess = new Update();worker.workProcess.ticker = ticker;workers.Add(ticker, worker);}worker = (Worker)workers[ticker];IStockServiceCallback c = OperationContext.Current.GetCallbackChannel(); lock (worker.workProcess.callbacks) { worker.workProcess.callbacks.Add(c); } Thread t = new Thread(new ThreadStart(worker.workProcess.SendUpdateToClient)); t.IsBackground = true; t.Start(); } public StockPrice GetStockPrice(string ticker) { StockPrice p = new StockPrice(); Console.WriteLine("{0}: GetPrice called on thread {1}", DateTime.Now, Thread.CurrentThread.ManagedThreadId); p.Price = 94.85; lock (locker) { p.CallsCounter = ++callsCounter; } Thread.Sleep(1000); return p; } #endregion } public class Update { public string ticker; public List callbacks = new List(); public void SendUpdateToClient() { Random w = new Random(); Random p = new Random(); for (int i = 0; i < 10; i++) { Thread.Sleep(w.Next(5000)); lock (callbacks) { foreach (IStockServiceCallback callback in callbacks) { try { callback.PriceUpdate("msft", 100.00 + p.NextDouble()); } catch (Exception ex) { Console.WriteLine("Error sending cache to client:{0}", ex.Message); } } } } } }
执行结果
调试状态下直接报出错误信息
通过配置文件暴露服务行为
实现IServiceBehavior,代码:
public class MyServiceBehavior : IServiceBehavior{string evaluationKey;string evaluationType;public MyServiceBehavior(string evaluationKey, string evaluationType){this.evaluationKey = evaluationKey;this.evaluationType = evaluationType;}#region IServiceBehavior Memberspublic void AddBindingParameters(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase, Collection endpoints, BindingParameterCollection bindingParameters) { } public void ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase) { } public void Validate(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase) { if (evaluationType.Equals("Enterprise", StringComparison.OrdinalIgnoreCase) & !evaluationKey.Equals("SuperSecretEvaluationKey", StringComparison.OrdinalIgnoreCase)) { throw new Exception(string.Format("Invalid evaluation key. Type:{0}", evaluationType)); } } #endregion }
配置:
转载于:https://www.cnblogs.com/jerryshi/archive/2011/10/21/2215965.html
自定义 Behavior相关推荐
- 红橙Darren视频笔记 CoordinatorLayout:实现自定义behavior
效果: 目标:利用CoordinatorLayout实现自定义behavior ,顶部的TitleBar和底部的ActionBar实现能够随着手势自由显示和隐藏 activity中使用了recycle ...
- WCF中使用自定义behavior提示错误的解决方法
WCF中使用自定义behavior提示错误的解决方法 参考文章: (1)WCF中使用自定义behavior提示错误的解决方法 (2)https://www.cnblogs.com/shenba/arc ...
- layui totalRow 多层嵌套json_自定义 Behavior,实现嵌套滑动、平滑切换周月视图的日历...
使用 CoordinateLayout 可以协调它的子布局,实现滑动效果的联动,它的滑动效果由 Behavior 实现.以前用过小米日历,对它滑动平滑切换日月视图的效果印象深刻.本文尝试用自定义 Be ...
- 自定义Behavior的艺术探索-仿UC浏览器主页
出处:http://www.jianshu.com/p/f7989a2a3ec2 前言&效果预览 最近几个周末基本在研究CoordinatorLayout控件和自定义Behavior当中,这期 ...
- 自定义 behavior - 完美仿 QQ 浏览器首页,美团商家详情页
前言 记得两年前的时候,曾写过自定义 behavior 的文章 自定义 Behavior -仿新浪微博发现页的实现,到现在差不多有一万多的阅读量吧. image 今天,对该 behavior 进行升级 ...
- Android仿小米时钟嵌套滑动(NestedScroll, 自定义behavior)
最近无聊刷手机的时候, 发现小米时钟的嵌套滑动很有意思, 就试着做了下 先上对比图: 分析下小米时钟的滑动 闹钟列表 向上滑动时, 时钟面 透明度上升, 快到最大滑动时逐渐显示数字时钟. 在闹钟列表向 ...
- Android自定义Behavior出现This graph contains cyclic dependencies
最近刚开始学习使用CoordinatorLayout,并且自定义Behavior,因为项目要求,要在webview滑动的时候,headview要跟着滑动改变自身大小,并且要使webview在headv ...
- Android CoordinatorLayout 自定义Behavior 高仿美团商家详情界面 实现页面内容复杂联动效果
内容如题 效果如下 顺带涉及到: Scroller+Handler 实现View自动滑动 View属性动画 触摸事件分发机制 ConstraintLayout约束布局 emmmm 实现参考: Cons ...
- CoordinatorLayout高级用法-自定义Behavior
在新的support design中,CoordinatorLayout可以说是最重要的一个控件了,CoordinatorLayout给我们带来了一种新的事件的处理方式--behavior,你是不是还 ...
最新文章
- 报错解决:ERROR: While executing gem ... (Gem::CommandLineError)
- 人在职场,干得好真的不如汇报得好?
- 50年前就已讨论的数据中心隐私问题
- react 不能往组件中传入属性的值为 undefined
- win10开启wsl系统,让我们愉快的在windows上使用Linux
- CentOS系统启动流程及GRUB文件说明
- Android添加Header请求参数实例,java响应header请求实现demo
- studio 快捷键
- SAP License:发票校验抬头税码选择清单
- 我笑了一天的签名。。。
- 完美替代Windows任务计划程序 —— 定时执行专家
- 智能隐形眼镜的研究进展与挑战
- ps -ef|grep 命令解释
- [Vue][transition]Vue中实现类似JQuery中slideUp slideDown的滑动显示隐藏过渡动画效果
- html向上无间隔滚动文字(图片)
- Python 之父加入微软
- 亚创集团任命联合创始人兼总裁欧阳云为CEO 重申继续推进IPO
- AI人工智能—数据标注的主要类型和标注注意事项
- 谈新手Java SE JDK 下载那个版本好!
- 全国计算机等级考试二级C知识点
热门文章
- uniapp 自定义基座后软件打不开,屡次关闭
- FPGA的设计艺术(7)STA实战之SmartTime时序约束及分析示例(II)
- Java范例开发大全源程序
- SSH跨平台终端工具tabby推荐
- Android 实现书籍翻页效果----原理篇
- Lotus的2008
- python程序语言和机器人控制-利用树莓派+Python语言制作一部机器人就是如此简单!...
- 绝地求生大逃杀错误服务器维护,绝地求生 Bad Service Version 错误问题解决方法
- 电影死刑犯的主题歌: Nickelback.-.Savin'.Me
- 计算机毕业设计nodejsLIN广告设计网站系统