我在这里有两个查询:-
1)Microsoft.ServiceModel.Web.RequestInterceptor and System.ServiceModel.Dispatcher.DispatchRuntime.MessageInspectors (IdispatchMessageInterceptor)
的基本区别是什么
两者似乎都是请求/消息拦截器,可用于在请求管道中实现自定义验证/拦截器。
什么时候在另一个上使用一个?
2) 此外,如何在RouteTable.Routes.Add(new ServiceRoute())
中插入RequestInterceptor
我有这样的课-
public class AuthenticationInterceptor : RequestInterceptor
{
//Authentication logic goes here......
}
和这样的路线定义:-
RouteTable.Routes.Add(new ServiceRoute(routePrefix, new MyServiceHostFactory(container, (sh) => {
foreach (System.ServiceModel.Dispatcher.ChannelDispatcher cd in sh.ChannelDispatchers)
{
foreach (System.ServiceModel.Dispatcher.EndpointDispatcher ed in cd.Endpoints)
{
ed.DispatchRuntime.MessageInspectors.Add(new AuthenticationInterceptor());
}
}
return sh; })));
以下是MyServiceHostFactory
:-的定义
public MyServiceHostFactory(IocContainer container, Func<ServiceHost, ServiceHost> createservicehost = null);
现在它抛出以下错误:-
The best overloaded method match for 'System.Collections.Generic.SynchronizedCollection<System.ServiceModel.Dispatcher.IDispatchMessageInspector>.Add(System.ServiceModel.Dispatcher.IDispatchMessageInspector)' has some invalid arguments
在这一行:-
ed.DispatchRuntime.MessageInspectors.Add(new AuthenticationInterceptor());
我知道为什么,这只是因为我试图在MessageInspector中连接RequestInterceptor。两者都有不同的接口层次结构。
那我在这里该怎么办?
编辑:
另外请注意,我不能更改AuthenticationInterceptor逻辑,因为代码不在我的控制范围内。
以下是您问题的答案(您需要通读第2点才能稍微了解拦截器和检查员):
1.错误的解决方案(您需要将代码逻辑添加到其中)
在以下代码中实现IDispatchMessageInspector。请注意,以下类的名称应该更改为检查器,但正如您所提到的,您不能更改它,因此您应该在这里实现接口。否则,建议创建另一个具有MatchingInspector后缀和实现的类。
public class AuthenticationInterceptor : RequestInterceptor, IDispatchMessageInspector
{
//Authentication logic goes here......
object IDispatchMessageInspector.AfterReceiveRequest(ref System.ServiceModel.Channels.Message request, System.ServiceModel.IClientChannel channel, System.ServiceModel.InstanceContext instanceContext)
{
//Your code here.
}
void IDispatchMessageInspector.BeforeSendReply(ref System.ServiceModel.Channels.Message reply, object correlationState)
{
//Your code here.
}
}
2.RequestInterceptor和MessageInspectors之间的差异
在任何客户端-服务器通信中,都可能存在两个重要的通信阶段。第一,当客户端与服务器建立连接时,第二,当它们都进行通信时。
当建立连接时,尝试建立连接的客户端不一定是有效的客户端。它也可能是未经授权的请求,或者该请求可能是有效的,但不是针对目标服务器的,并且需要授权或重新路由连接。
重新路由的一个很好的例子是:
您希望区域客户端/服务器避免跨区域通信,但其中一个客户端(有效)试图连接到不同的区域服务器。
您希望服务器有选择地决定是否允许少数特殊用户进行跨区域客户端-服务器通信。
可能会有更复杂的重新路由场景,这超出了这个答案的范围。
因此,在WCF中,Rest启动工具包为您提供了在连接建立阶段拦截请求的额外能力。拦截器(在您的情况下是AuthenticationInterceptor)应该对这些请求进行身份验证,如果请求无效,它可以记录必要的条目,并拒绝处理来自被拒绝的客户端/会话的任何通信。
拥有RequestInterceptor有很多好处:
它有助于我们在非常早期的阶段验证传入的请求。
它可以帮助我们构建自定义验证器或重新路由组件。
它在请求阶段本身阻止任何进一步的消息处理,这对于避免WCF服务/服务器产生不必要的负载非常重要。
消息检查器:当请求得到验证并且连接建立良好时,MessageInspectors可以被视为客户端-服务器通信的第二阶段的一部分,因此客户端-服务器必须通过相互传递消息来开始通信。现在,在您的应用程序环境中,可以使用二进制、xml或json序列化格式传递消息。可能存在适用的加密。
一个例子是,有可能消息从客户端a到达并提供给服务器B,现在服务器将其排队到另一个服务器C,该服务器C可以等待来自另一服务器D的更多信息。一旦服务器D提供了信息,队列中有消息的服务器C就进一步加入从服务器B和服务器D接收的原始消息,将其提供给另一个服务进行反序列化并将其转换为有意义的内容,这些内容可以返回给服务器B,B将其返回给客户端A。
相当复杂,对吧?但是,像使用移动PIN的信用卡支付这样的多服务器身份验证在某种程度上也以类似的方式工作,尽管可能不完全相同,但甚至更复杂。
在WCF中,拦截器和检查员可以协同工作,并且他们的职责不同。拦截器验证最终用户/连接/重新路由,检查器验证/处理消息。
几点:
您可以通过在客户端实现IClientMessageInspector,在服务器端实现IDispatchMessageInspecter来构建自己的消息检查器。
如果您同时拥有客户端和服务器组件,则可以在一个类中实现这两个接口。
在这里,在您的情况下,似乎需要实现IDispatchMessageInspector。
实现IDispatchMessageInspector的类不会像我之前提到的那样进行拦截,而是用于"检查"传入消息和任何传出消息,当消息从客户端到达时,可以使用配置钩住该Inspector。
请注意,此时在检查器级别,到达的任何消息都已在各个通道堆栈级别进行处理,并分配给WCF服务将处理此请求的对象。如果您正在使用介于两者之间的任何加密,则该消息已被解密。但是,该消息尚未反序列化。
拥有自定义检查器的一个用途是,您的系统可能实现自定义序列化格式,如(银行中的SWIFT/FIX协议)或另一级别的zip/unzip编码等。
这个自定义检查器可以反序列化数据,并将其提供给您的组件COMP,COMP实际上是用来处理反序列化数据的。
IDispatchMessageInspector接口有两种方法需要实现:
a) AfterReceiveRequest和
b) BeforeSendReply(引用消息,对象)。
AfterReceiveRequest是一种可以取消序列化数据并将其提供给COMP的方法,BeforeSendReply是一种再次序列化数据并对消息执行任何操作的方法。
您可以使用行为为web服务接收到的每条消息附加MessageInspectors。自定义拦截器和检查器都主要用于企业平台或高度可定制的平台。
希望这个答案对你有帮助。你可以在以下链接上阅读更多(可能你已经浏览了第一个):
http://msdn.microsoft.com/en-us/library/ee391967.aspx
http://msdn.microsoft.com/en-us/library/aa717047(v=vs.110).aspx
问候Kajal