IClientMessageInspector IDispatchMessageInspector
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks; using System.ServiceModel;
using System.ServiceModel.Dispatcher;
using System.ServiceModel.Description;
using System.ServiceModel.Channels; namespace MyLib
{
/// <summary>
/// 消息拦截器
/// </summary>
public class MyMessageInspector:IClientMessageInspector,IDispatchMessageInspector
{
void IClientMessageInspector.AfterReceiveReply(ref Message reply, object correlationState)
{
Console.WriteLine("客户端接收到的回复:\n{0}", reply.ToString());
} object IClientMessageInspector.BeforeSendRequest(ref Message request, IClientChannel channel)
{
Console.WriteLine("客户端发送请求前的SOAP消息:\n{0}", request.ToString());
return null;
} object IDispatchMessageInspector.AfterReceiveRequest(ref Message request, IClientChannel channel, InstanceContext instanceContext)
{
Console.WriteLine("服务器端:接收到的请求:\n{0}", request.ToString());
return null;
} void IDispatchMessageInspector.BeforeSendReply(ref Message reply, object correlationState)
{
Console.WriteLine("服务器即将作出以下回复:\n{0}", reply.ToString());
}
} /// <summary>
/// 插入到终结点的Behavior
/// </summary>
public class MyEndPointBehavior : IEndpointBehavior
{
public void AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters)
{
// 不需要
return;
} public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime)
{
// 植入“偷听器”客户端
clientRuntime.ClientMessageInspectors.Add(new MyMessageInspector());
} public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher)
{
// 植入“偷听器” 服务器端
endpointDispatcher.DispatchRuntime.MessageInspectors.Add(new MyMessageInspector());
} public void Validate(ServiceEndpoint endpoint)
{
// 不需要
return;
}
} }
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks; using System.Runtime;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Description; namespace WCFServer
{
class Program
{
static void Main(string[] args)
{
// 服务器基址
Uri baseAddress = new Uri("http://localhost:1378/services");
// 声明服务器主机
using (ServiceHost host = new ServiceHost(typeof(MyService), baseAddress))
{
// 添加绑定和终结点
WSHttpBinding binding = new WSHttpBinding();
host.AddServiceEndpoint(typeof(IService), binding, "/test");
// 添加服务描述
host.Description.Behaviors.Add(new ServiceMetadataBehavior { HttpGetEnabled = true });
// 把自定义的IEndPointBehavior插入到终结点中
foreach (var endpont in host.Description.Endpoints)
{
endpont.EndpointBehaviors.Add(new MyLib.MyEndPointBehavior());
}
try
{
// 打开服务
host.Open();
Console.WriteLine("服务已启动。");
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
Console.ReadKey();
}
}
} [ServiceContract(Namespace = "MyNamespace")]
public interface IService
{
[OperationContract]
int AddInt(int a, int b);
[OperationContract]
Student GetStudent();
[OperationContract]
CalResultResponse ComputingNumbers(CalcultRequest inMsg);
} [ServiceBehavior(IncludeExceptionDetailInFaults = true)]
public class MyService : IService
{
public int AddInt(int a, int b)
{
return a + b;
} public Student GetStudent()
{
Student stu = new Student();
stu.StudentName = "小明";
stu.StudentAge = 22;
return stu;
} public CalResultResponse ComputingNumbers(CalcultRequest inMsg)
{
CalResultResponse rmsg = new CalResultResponse();
switch (inMsg.Operation)
{
case "加":
rmsg.ComputedResult = inMsg.NumberA + inMsg.NumberB;
break;
case "减":
rmsg.ComputedResult = inMsg.NumberA - inMsg.NumberB;
break;
case "乘":
rmsg.ComputedResult = inMsg.NumberA * inMsg.NumberB;
break;
case "除":
rmsg.ComputedResult = inMsg.NumberA / inMsg.NumberB;
break;
default:
throw new ArgumentException("运算操作只允许加、减、乘、除。");
break;
}
return rmsg;
}
} [DataContract]
public class Student
{
[DataMember]
public string StudentName;
[DataMember]
public int StudentAge;
} [MessageContract]
public class CalcultRequest
{
[MessageHeader]
public string Operation;
[MessageBodyMember]
public int NumberA;
[MessageBodyMember]
public int NumberB;
} [MessageContract]
public class CalResultResponse
{
[MessageBodyMember]
public int ComputedResult;
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks; namespace WCFClient
{
class Program
{
static void Main(string[] args)
{
WS.ServiceClient client = new WS.ServiceClient();
// 记得在客户端也要插入IEndPointBehavior
client.Endpoint.EndpointBehaviors.Add(new MyLib.MyEndPointBehavior());
try
{
// 1、调用带元数据参数和返回值的操作
Console.WriteLine("\n20和35相加的结果是:{0}", client.AddInt(20, 35));
// 2、调用带有数据协定的操作
WS.Student student = client.GetStudent();
Console.WriteLine("\n学生信息---------------------------");
Console.WriteLine("姓名:{0}\n年龄:{1}", student.StudentName, student.StudentAge);
// 3、调用带消息协定的操作
Console.WriteLine("\n15乘以70的结果是:{0}", client.ComputingNumbers("乘", 15, 70));
}
catch (Exception ex)
{
Console.WriteLine("异常:{0}", ex.Message);
} client.Close();
Console.ReadKey();
}
}
}
/// <summary>
/// 消息拦截器
/// </summary>
public class MyMessageInspector:IClientMessageInspector,IDispatchMessageInspector
{
void IClientMessageInspector.AfterReceiveReply(ref Message reply, object correlationState)
{
//Console.WriteLine("客户端接收到的回复:\n{0}", reply.ToString());
return;
} object IClientMessageInspector.BeforeSendRequest(ref Message request, IClientChannel channel)
{
//Console.WriteLine("客户端发送请求前的SOAP消息:\n{0}", request.ToString());
// 插入验证信息
MessageHeader hdUserName = MessageHeader.CreateHeader("u", "fuck", "admin");
MessageHeader hdPassWord = MessageHeader.CreateHeader("p", "fuck", "");
request.Headers.Add(hdUserName);
request.Headers.Add(hdPassWord);
return null;
} object IDispatchMessageInspector.AfterReceiveRequest(ref Message request, IClientChannel channel, InstanceContext instanceContext)
{
//Console.WriteLine("服务器端:接收到的请求:\n{0}", request.ToString());
// 栓查验证信息
string un = request.Headers.GetHeader<string>("u", "fuck");
string ps = request.Headers.GetHeader<string>("p", "fuck");
if (un == "admin" && ps == "abcd")
{
Console.WriteLine("用户名和密码正确。");
}
else
{
throw new Exception("验证失败,滚吧!");
}
return null;
} void IDispatchMessageInspector.BeforeSendReply(ref Message reply, object correlationState)
{
//Console.WriteLine("服务器即将作出以下回复:\n{0}", reply.ToString());
return;
}
}
IClientMessageInspector IDispatchMessageInspector的更多相关文章
- 重温WCF之消息拦截与篡改(八)
我们知道,在WCF中,客户端对服务操作方法的每一次调用,都可以被看作是一条消息,而且,可能我们还会有一个疑问:如何知道客户端与服务器通讯过程中,期间发送和接收的SOAP是什么样子.当然,也有人是通过借 ...
- WCF消息拦截,利用消息拦截做身份验证服务
本文参考 http://blog.csdn.net/tcjiaan/article/details/8274493 博客而写 添加对信息处理的类 /// <summary> /// 消 ...
- 传说中的WCF(10):消息拦截与篡改
我们知道,在WCF中,客户端对服务操作方法的每一次调用,都可以被看作是一条消息,而且,可能我们还会有一个疑问:如何知道客户端与服务器通讯过 程中,期间发送和接收的SOAP是什么样子.当然,也有人是通过 ...
- WCF不用证书实现验证(messageheader)
上文WCF进阶:将消息正文Base64编码中介绍了实现自定义MessageInspector来记录消息和实现自定义Formatter来改写消息,本文介绍一下在WCF中使用SoapHeader进行验证的 ...
- 传说中的WCF:消息拦截与篡改
我们知道,在WCF中,客户端对服务操作方法的每一次调用,都可以被看作是一条消息,而且,可能我们还会有一个疑问:如何知道客户端与服务器通讯过程中,期间发送和接收的SOAP是什么样子.当然,也有人是通过借 ...
- wcf利用IDispatchMessageInspector实现接口监控日志记录和并发限流
一般对于提供出来的接口,虽然知道在哪些业务场景下才会被调用,但是不知道什么时候被调用.调用的频率.接口性能,当出现问题的时候也不容易重现请求:为了追踪这些内容就需要把每次接口的调用信息给完整的记录下来 ...
- 关于WEB Service&WCF&WebApi实现身份验证之WCF篇(2)
因前段时间工作变动(换了新工作)及工作较忙暂时中断了该系列文章,今天难得有点空闲时间,就继续总结WCF身份验证的其它方法.前面总结了三种方法(详见:关于WEB Service&WCF& ...
- WCF自定义扩展,以实现aop!
引用地址:https://msdn.microsoft.com/zh-cn/magazine/cc163302.aspx 使用自定义行为扩展 WCF Aaron Skonnard 代码下载位置: S ...
- [WCF]设置拦截器捕捉到request和reply消息
WCF进阶学习ing... 在熟练掌握了ABC的使用以后,就开始想着去了解WCF是怎么通信的了.首先是服务描述语言wsdl,它定义了服务的描述等等,用于让外界知道这个服务的ABC是什么.另外一个比较重 ...
随机推荐
- Spark通过修改DataFrame的schema给表字段添加注释(转载)
转载自:https://www.jianshu.com/p/e4c90dc08935 1.需求背景 通过Spark将关系型数据库(以Oracle为例)的表同步的Hive表,要求用Spark建表,有字段 ...
- JS实现动态添加和删除div
实现方式一:只在最后一个数据中动态添加或者删除 | 背景需要做一个页面,页面可以输入参数,点击确认按钮可以发请求给某接口.但是接口的某个字段是数组类型,所以在页面上需要实现添加或者删除元素的功能. | ...
- QDateTime获取当前时间的时间戳
QdateTime获取当前时间的时间戳作为图片名 QDateTime qdt1 = QDateTime::currentDateTime();QString timeStr = qdt1.toStri ...
- osg编译日志
1>------ 已启动全部重新生成: 项目: ZERO_CHECK, 配置: Debug x64 ------1> Checking Build System1> CMake do ...
- 全面系统Python3入门+进阶-1-4 Python的缺点
结束
- 123457123456#2#----com.ppGame.XueYingYu76--前拼后广--儿童英语_pp
com.ppGame.XueYingYu76--前拼后广--儿童英语_pp
- Spring MVC 保存并获取属性参数
在开发控制器的时候,有时也需要保存对应的数据到这些对象中去,或者从中获取数据.而Spring MVC给予了支持,它的主要注解有3个:@RequestAttribute.@SessionAttribut ...
- LabWindows/CVI入门之第四章:库文件(转)
按语: 在参考CVI参考书使用CVI生成动态库后,在另一工程中调用DLL ,编译通不过,后参考此文,豁然开朗. http://blog.sina.com.cn/s/blog_6373e9e60101b ...
- Python - Django - 在 CBV 中使用装饰器
urls.py: from django.conf.urls import url from app02 import views urlpatterns = [ # app02 url(r'^app ...
- 基于EasyDSS流媒体解决方案创建视频点播、短视频、视频资源库等视频播放系统
随着前端技术的不断发展,视频点播早已不再是IE6时代的浏览器嵌入式Windows Media Player.也不是后来的flash media player需要的rtmp点播流,现在能够唯一满足全终端 ...