[转]十五天精通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

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[].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即可,有了上面的思想,我想下面这些使用起来都不是问题吧。。。
[转]十五天精通WCF——第九天 高级玩法之自定义Behavior的更多相关文章
- 十五天精通WCF——第九天 高级玩法之自定义Behavior
终于我又看完了二期爱情保卫战,太酸爽了,推荐链接:http://www.iqiyi.com/a_19rrgublqh.html?vfm=2008_aldbd,不多说,谁看谁入迷,下面言归正传, 看看这 ...
- 十五天精通WCF——第十一天 如何对wcf进行全程监控
说点题外话,我们在玩asp.net的时候,都知道有一个叼毛玩意叫做“生命周期”,我们可以用httpmodule在先于页面的page_load中 做一些拦截,这样做的好处有很多,比如记录日志,参数过滤, ...
- [转]十五天精通WCF——第十一天 如何对wcf进行全程监控
说点题外话,我们在玩asp.net的时候,都知道有一个叼毛玩意叫做“生命周期”,我们可以用httpmodule在先于页面的page_load中 做一些拦截,这样做的好处有很多,比如记录日志,参数过滤, ...
- 十五天精通WCF——第一天 三种Binding让你KO80%的业务
转眼wcf技术已经出现很多年了,也在.net界混的风生水起,同时.net也是一个高度封装的框架,作为在wcf食物链最顶端的我们所能做的任务已经简单的不能再简单了, 再简单的话马路上的大妈也能写wcf了 ...
- 十五天精通WCF——第十四天 一起聊聊FaultException
我们在玩web编程的时候,可能你会不经意的见到一些http500的错误,我想你应该不会陌生的,原因你应该也知道,服务器异常嘛, 这时候clr会把这个未处理的异常抛给iis并且包装成http500的错 ...
- [转]十五天精通WCF——第十四天 一起聊聊FaultException
我们在玩web编程的时候,可能你会不经意的见到一些http500的错误,我想你应该不会陌生的,原因你应该也知道,服务器异常嘛, 这时候clr会把这个未处理的异常抛给iis并且包装成http500的错 ...
- [转]十五天精通WCF——第一天 三种Binding让你KO80%的业务
转眼wcf技术已经出现很多年了,也在.net界混的风生水起,同时.net也是一个高度封装的框架,作为在wcf食物链最顶端的我们所能做的任务已经简单的不能再简单了, 再简单的话马路上的大妈也能写wcf了 ...
- 十五天精通WCF——终结篇 那些你需要注意的坑
终于一路走来,到了本系列的最后一篇了,这一篇也没什么好说的,整体知识框架已经在前面的系列文章中讲完了,wcf的配置众多,如果 不加一些指定配置,你可能会遇到一些灾难性的后果,快来一睹为快吧. 一: 第 ...
- 十五天精通WCF——第十三天 用WCF来玩Rest
在我们玩wcf的时候,都会潜意识的觉得wcf就是通过soap协议交换消息的,并且可以在basic,tcp,msmq等等绑定中任意切换, 牛逼的一塌糊涂,但是呢,如果说哪一天wcf不再使用soap协议, ...
随机推荐
- js的45个技巧
JavaScript是一个绝冠全球的编程语言,可用于Web开发.移动应用开发(PhoneGap.Appcelerator).服务器端开发(Node.js和Wakanda)等等.JavaScript还是 ...
- js返回上一层
Javascript 返回上一页 1. Javascript 返回上一页 history.go(-1), 返回两个页面: history.go(-2); 2. history.back(). wind ...
- 手机不ROOT使用xposed框架-微信群同步-微咖讲师-安装教程
其实已经很多人知道Xposed框架这个便捷的工具,但是呢由于框架必须root,导致很多用户望而却步,今天就来教下大家,如何不root玩转xposed框架 1.下载 SandVxposed免root 虚 ...
- akka设计模式系列-慎用ask
慎用ask应该是Akka设计的一个准则,很多时候我们应该禁用ask.之所以单独把ask拎出来作为一篇博文,主要是akka的初学者往往对ask的使用比较疑惑. "Using ask will ...
- 分享两篇关于ActionBar样式设置的博客
http://www.open-open.com/lib/view/open1373981182669.html http://blog.csdn.net/xyz_lmn/article/detail ...
- 【知识总结】回文自动机(Palindrome_Automaton)
参考资料:Palindromic Tree--回文树[处理一类回文串问题的强力工具](请注意,其中似乎有一些错误) 回文自动机似乎和回文树是同一个东西qwq? 回文自动机(PAM)是一种处理回文串的工 ...
- scrapy 框架持久化存储
1.基于终端的持久化存储 保证爬虫文件的parse方法中有可迭代类型对象(通常为列表或字典)的返回,该返回值可以通过终端指令的形式写入指定格式的文件中进行持久化操作. # 执行输出指定格式进行存储:将 ...
- Java中的异常注意点
在java中 使用throw关键字抛出异常 使用throws关键字声明异常 public static void main(String[] args) throws Exception{ ...
- THREE.js代码备份——webgl - scene animation(通过加载json文件来加载动画和模型)
<!DOCTYPE html> <html lang="en"> <head> <title>three.js webgl - sc ...
- PHP 之ftp客户端类封装实现
<?php /** * Class FtpClient */ class FtpClient { private $host = '';//远程服务器地址 private $user = ''; ...