我在这里有两个问题: -
1)Microsoft.ServiceModel.Web.RequestInterceptor and System.ServiceModel.Dispatcher.DispatchRuntime.MessageInspectors (IdispatchMessageInterceptor)
两者似乎都是请求/消息拦截器,可用于在请求管道中实现自定义验证/拦截器。
何时在另一个上使用?
2)如何在 RequestInterceptor
RouteTable.Routes.Add(new ServiceRoute())
我有这样的课 -
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逻辑更改为不受我控制的代码。
答案 0 :(得分:10)
以下是您的问题的答案(您需要阅读第2点以了解拦截器和检查员一点):
<强> 1。错误解决方案(您需要将代码逻辑添加到其中)
在以下代码中实现IDispatchMessageInspector。请注意,以下类的名称应更改为检查器,但正如您所提到的,您无法更改它,因此您应在此处实现该接口。否则,建议使用Matching Inspector后缀和实现创建另一个类。
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,它可以等待来自另一个服务器D的更多信息。一旦服务器D提供了信息,在队列中具有消息的服务器C进一步加入从服务器B和服务器D接收的原始消息,将其提供给另一个服务以反序列化并将其转换为有意义的内容,可以将其返回给服务器B并且B将其返回给客户端A 。
相当复杂,对吧?但是,使用移动密码通过信用卡支付的多服务器身份验证在某种程度上可以以类似的方式运行,但可能不完全相同,但更复杂。
在WCF中,拦截器和检查员可以一起工作,他们的职责也不同。拦截器验证最终用户/连接/重新路由,并且Inspector验证/处理消息。
几点:
您可以通过为客户端实现IClientMessageInspector和在服务器端实现IDispatchMessageInspector来构建自己的消息检查器。
如果您是客户端和服务器组件的所有者,则可以在单个类中实现这两个接口。
在这种情况下,您似乎需要实现IDispatchMessageInspector。
实现IDispatchMessageInspector的类不像我之前提到的那样拦截,而是用于检查&#39;传入消息和任何传出消息,当消息从客户端到达时,可以使用配置挂钩此Inspector。
请注意,此时在Inspector级别,任何到达的消息都已在各种通道堆栈级别处理,并分配给哪个WCF服务将处理此请求。如果您在其间使用任何加密,则该消息已被解密。但是,该消息尚未反序列化。
使用您的自定义Inspector可能是您的系统可能实现自定义序列化格式(如银行中的SWIFT / FIX协议)或其他级别的zip / unzip编码等。
此自定义检查器可以反序列化数据并将其提供给组件COMP,这实际上是用于处理反序列化的数据。
IDispatchMessageInspector接口有两个您需要实现的方法:
a)AfterReceiveRequest和
b)BeforeSendReply(ref Message,Object)。
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