IDIspatchMessageInspector

IDIspatchMessageInspector

我有两个问题:
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中连接请求拦截器。两者都有不同的接口层次结构。
那我该怎么办?
编辑:
另外请注意,我不能更改authenticationinterceptor逻辑,因为代码不在我的控制之下。

最佳答案

以下是您问题的答案(您需要通读第2点,以便稍微了解拦截器和检查器):
一。错误的解决方案(需要添加代码逻辑)
在以下代码中实现IDispatchMessageInspector。请注意,以下类的名称应该更改为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 starter工具包提供了在连接建立阶段拦截请求的额外能力。拦截器(在您的情况下是authenticationinterceptor)应该对这些请求进行身份验证,如果请求无效,它可以记录必要的条目,并拒绝进一步处理来自这个被拒绝的客户端/会话的任何通信。
拥有requestinterceptor有很多好处:
它帮助我们在很早的阶段就验证传入的请求。
它可以帮助我们构建自定义身份验证器或重新路由组件。
它会在请求阶段本身阻止任何进一步的消息处理,这对于保持wcf服务/服务器不必要的负载非常重要。
消息检查器:
当请求被验证并且连接建立良好时,可以将MessageInspectors视为客户机-服务器通信的第二阶段的一部分,因此现在是客户机-服务器必须通过相互传递消息开始通信的时候。现在,在您的应用程序环境中,可以使用二进制、XML或JSON序列化格式传递消息。可能有适用的加密。
一个例子是,一条消息可能从客户端A到达并被发送到服务器B,现在服务器将其排队到另一个服务器C,该服务器C可以等待来自另一个服务器D的更多信息。一旦服务器D提供了该信息,队列中有该消息的服务器C将进一步连接从服务器B和服务器D接收的原始消息,将其提供给另一个服务进行反序列化并将其转换为有意义的内容,该内容可以返回到服务器B,而B将其返回到客户端A。
很复杂,对吧?但是,像使用移动pin的信用卡支付这样的多服务器身份验证的工作方式有点类似,虽然可能并不完全相同,但更为复杂。
在wcf中,拦截器和检查员可以协同工作,他们的职责是不同的。拦截器验证最终用户/连接/重新路由,检查器验证/处理消息。
有几点:
通过在客户端实现iclientMessageInspector和在服务器端实现idispatchMessageInspector,可以构建自己的消息检查器。
如果同时拥有客户端和服务器组件,则可以在单个类中实现这两个接口。
在这里,在您的情况下,似乎需要实现IDispatchMessageInspector。
实现idispatchMessageInspector的类不会像我前面提到的那样进行拦截,而是用来“检查”传入消息和任何传出消息,当消息从客户端到达时,可以使用配置挂接此检查器。
请注意,此时在检查器级别,任何到达的消息都已在不同的通道堆栈级别进行处理,并分配给WCF服务处理此请求。如果您在这两者之间使用任何加密,则消息已被解密。但是,消息尚未反序列化。
使用自定义检查器的一个好处是,您的系统可能实现自定义序列化格式,如(银行业中的swift/fix协议)或其他级别的zip/unzip编码等。
此自定义检查器可以反序列化数据并将其提供给组件comp,组件comp实际上是用来处理反序列化数据的。
IDispatchMessageInspector接口有两个需要实现的方法:
a)接管后
b)beforesendreply(ref消息,对象)。
afterreceiverequest是将数据取消序列化并交给comp的方法,beforesendreply是再次序列化数据并对消息执行任何操作的方法。
您可以使用行为为您的web服务接收的每个消息附加消息检查器。
两者都是,自定义拦截器和检查器主要用于企业平台或高度可定制的平台。
希望这个答案对你有帮助。您可以在以下链接上阅读更多内容(可能您已经阅读了第一个链接):
http://msdn.microsoft.com/en-us/library/ee391967.aspx
http://msdn.microsoft.com/en-us/library/aa717047(v=vs.110).aspx
当做
卡久

10-05 20:38