“多个过滤器匹配。”在 WCF 中对多个端点使用相同的地址时
因此,出于一些组织方面的考虑,我将最初的单个接口合约拆分为两个单独的接口合约。现在,我只有一个类实现这两个接口,并且我希望通过 WCF 将它们全部用作 REST 服务。 下面列出了合同:
第一:
[ServiceContract]
public interface INotification
{
[OperationContract]
[WebGet]
XElement GetInfo(string appID);
[OperationContract]
[WebGet]
void RegisterRID(string appID, string registrationID);
}
第二:
[ServiceContract]
public interface IPlanning
{
[OperationContract]
[WebGet]
XElement PlanTrip(string toDestination, string fromDestination, int year, int month, int day, int hour, int minute, string appID);
[OperationContract]
[WebGet]
XElement PlanTripDelayed(string toDestination, string fromDestination, int year, int month, int day, int hour, int minute, string appID);
[OperationContract]
[WebGet]
XElement PlanTripLoc(string toDestination, string fromLat, string fromLong, int year, int month, int day, int hour, int minute, string appID);
}
我的 app.config 如下所示:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>
<behaviors>
<endpointBehaviors>
<behavior name="RESTFriendly">
<webHttp />
</behavior>
</endpointBehaviors>
</behaviors>
<services>
<service name="TravelPlannerWebService.Domain.Entity.ETravelPlanner">
<endpoint binding="webHttpBinding" bindingConfiguration="" contract="TravelPlannerWebService.Acquaintance.IPlanning" behaviorConfiguration="RESTFriendly" />
<endpoint binding="webHttpBinding" bindingConfiguration="" contract="TravelPlannerWebService.Acquaintance.INotification" behaviorConfiguration="RESTFriendly" />
<host>
<baseAddresses>
<add baseAddress="http://localhost:80" />
</baseAddresses>
</host>
</service>
</services>
</system.serviceModel>
问题是,每当我尝试使用两个接口时,都会收到错误。通过查看我的 app_tracelog.svclog (我在这里故意从 app.config 中删除了调试代码),我可以看到出现以下错误:
消息:多个过滤器匹配。
堆栈跟踪:
System.ServiceModel.Dispatcher.EndpointDispatcherTable.LookupInCache(Message message, Boolean& addressMatched)
System.ServiceModel.Dispatcher.EndpointDispatcherTable.Lookup(Message message, Boolean& addressMatched)
System.ServiceModel.Dispatcher.ChannelHandler.GetDatagramChannel(Message message, EndpointDispatcher& endpoint, Boolean& addressMatched)
System.ServiceModel.Dispatcher.ChannelHandler.EnsureChannelAndEndpoint(RequestContext request)
System.ServiceModel.Dispatcher.ChannelHandler.TryRetrievingInstanceContext(RequestContext request)
System.ServiceModel.Dispatcher.ChannelHandler.HandleRequest(RequestContext request, OperationContext currentOperationContext)
System.ServiceModel.Dispatcher.ChannelHandler.AsyncMessagePump(IAsyncResult result)
System.ServiceModel.Dispatcher.ChannelHandler.OnAsyncReceiveComplete(IAsyncResult result)
System.Runtime.Fx.AsyncThunk.UnhandledExceptionFrame(IAsyncResult result)
System.Runtime.AsyncResult.Complete(Boolean completedSynchronously)
System.Runtime.InputQueue`1.AsyncQueueReader.Set(Item item)
System.Runtime.InputQueue`1.EnqueueAndDispatch(Item item, Boolean canDispatchOnThisThread)
System.Runtime.InputQueue`1.EnqueueAndDispatch(T item, Action dequeuedCallback, Boolean canDispatchOnThisThread)
System.ServiceModel.Channels.SingletonChannelAcceptor`3.Enqueue(QueueItemType item, Action dequeuedCallback, Boolean canDispatchOnThisThread)
System.ServiceModel.Channels.HttpChannelListener.HttpContextReceived(HttpRequestContext context, Action callback)
System.ServiceModel.Channels.SharedHttpTransportManager.OnGetContextCore(IAsyncResult result)
System.ServiceModel.Channels.SharedHttpTransportManager.OnGetContext(IAsyncResult result)
System.Runtime.Fx.AsyncThunk.UnhandledExceptionFrame(IAsyncResult result)
System.Net.LazyAsyncResult.Complete(IntPtr userToken)
System.Net.LazyAsyncResult.ProtectedInvokeCallback(Object result, IntPtr userToken)
System.Net.ListenerAsyncResult.WaitCallback(UInt32 errorCode, UInt32 numBytes, NativeOverlapped* nativeOverlapped)
System.Threading._IOCompletionCallback.PerformIOCompletionCallback(UInt32 errorCode, UInt32 numBytes, NativeOverlapped* pOVERLAP)
我不知道如何解决这个问题。据我所知,从以下指南来看,这是对多个端点使用相同类型的正确方法。有什么想法吗?
So, due to some organizational concerns, I've split up what was intially a single interface contract into two seperate ones. Now, I have only one class implementing both interfaces, and I want to make them all available as REST-services through WCF.
The contracts are listed below:
1st:
[ServiceContract]
public interface INotification
{
[OperationContract]
[WebGet]
XElement GetInfo(string appID);
[OperationContract]
[WebGet]
void RegisterRID(string appID, string registrationID);
}
2nd:
[ServiceContract]
public interface IPlanning
{
[OperationContract]
[WebGet]
XElement PlanTrip(string toDestination, string fromDestination, int year, int month, int day, int hour, int minute, string appID);
[OperationContract]
[WebGet]
XElement PlanTripDelayed(string toDestination, string fromDestination, int year, int month, int day, int hour, int minute, string appID);
[OperationContract]
[WebGet]
XElement PlanTripLoc(string toDestination, string fromLat, string fromLong, int year, int month, int day, int hour, int minute, string appID);
}
My app.config looks like this:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>
<behaviors>
<endpointBehaviors>
<behavior name="RESTFriendly">
<webHttp />
</behavior>
</endpointBehaviors>
</behaviors>
<services>
<service name="TravelPlannerWebService.Domain.Entity.ETravelPlanner">
<endpoint binding="webHttpBinding" bindingConfiguration="" contract="TravelPlannerWebService.Acquaintance.IPlanning" behaviorConfiguration="RESTFriendly" />
<endpoint binding="webHttpBinding" bindingConfiguration="" contract="TravelPlannerWebService.Acquaintance.INotification" behaviorConfiguration="RESTFriendly" />
<host>
<baseAddresses>
<add baseAddress="http://localhost:80" />
</baseAddresses>
</host>
</service>
</services>
</system.serviceModel>
Problem being, whenever I try to use two interfaces, I get an error. Through looking at my app_tracelog.svclog (I've removed debug code from app.config intentionally here), I can see that I get the following error:
Message: Multiple filters matched.
Stack Trace:
System.ServiceModel.Dispatcher.EndpointDispatcherTable.LookupInCache(Message message, Boolean& addressMatched)
System.ServiceModel.Dispatcher.EndpointDispatcherTable.Lookup(Message message, Boolean& addressMatched)
System.ServiceModel.Dispatcher.ChannelHandler.GetDatagramChannel(Message message, EndpointDispatcher& endpoint, Boolean& addressMatched)
System.ServiceModel.Dispatcher.ChannelHandler.EnsureChannelAndEndpoint(RequestContext request)
System.ServiceModel.Dispatcher.ChannelHandler.TryRetrievingInstanceContext(RequestContext request)
System.ServiceModel.Dispatcher.ChannelHandler.HandleRequest(RequestContext request, OperationContext currentOperationContext)
System.ServiceModel.Dispatcher.ChannelHandler.AsyncMessagePump(IAsyncResult result)
System.ServiceModel.Dispatcher.ChannelHandler.OnAsyncReceiveComplete(IAsyncResult result)
System.Runtime.Fx.AsyncThunk.UnhandledExceptionFrame(IAsyncResult result)
System.Runtime.AsyncResult.Complete(Boolean completedSynchronously)
System.Runtime.InputQueue`1.AsyncQueueReader.Set(Item item)
System.Runtime.InputQueue`1.EnqueueAndDispatch(Item item, Boolean canDispatchOnThisThread)
System.Runtime.InputQueue`1.EnqueueAndDispatch(T item, Action dequeuedCallback, Boolean canDispatchOnThisThread)
System.ServiceModel.Channels.SingletonChannelAcceptor`3.Enqueue(QueueItemType item, Action dequeuedCallback, Boolean canDispatchOnThisThread)
System.ServiceModel.Channels.HttpChannelListener.HttpContextReceived(HttpRequestContext context, Action callback)
System.ServiceModel.Channels.SharedHttpTransportManager.OnGetContextCore(IAsyncResult result)
System.ServiceModel.Channels.SharedHttpTransportManager.OnGetContext(IAsyncResult result)
System.Runtime.Fx.AsyncThunk.UnhandledExceptionFrame(IAsyncResult result)
System.Net.LazyAsyncResult.Complete(IntPtr userToken)
System.Net.LazyAsyncResult.ProtectedInvokeCallback(Object result, IntPtr userToken)
System.Net.ListenerAsyncResult.WaitCallback(UInt32 errorCode, UInt32 numBytes, NativeOverlapped* nativeOverlapped)
System.Threading._IOCompletionCallback.PerformIOCompletionCallback(UInt32 errorCode, UInt32 numBytes, NativeOverlapped* pOVERLAP)
I have no idea how to solve this. As far as I can see, from following guides, this is the correct way to use the same type for multiple endpoints. Any ideas?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您可以使用以下命令并查看是否仍然出现异常:
您不能让 2 个不同的端点侦听同一地址。因此,我添加了地址属性来区分它们。
当托管在 IIS 中时,您的 URL 可能如下所示:
Can you use the below and see if you still get an exception:
You cannot have 2 different endpoints listening on the same address. Hence, I have added the address attribute to distinguish them.
Your URLs might be as follows when hosted in IIS:
简而言之,您需要记住
Indigo的 ABC ... 咳咳 ... WCF:地址、绑定、合约。事实上,您的服务的端点在同一物理类中实现,这与您的服务的调用者无关:对于外界来说,您的服务现在通过两个不同的服务端点公开:IPlanning 和 IPlanning。 I通知。
修改您的 app.config 文件的端点,以在其自己的地址(相对于您的服务的基地址)公开每个服务端点:
哦...您不需要所有 REST 友好端点行为内容 - webHttpBinding 默认情况下已经支持 httpGet。 :)
另外,我强烈鼓励您启用服务元数据(尤其是在开发时),因为这允许您使用工具生成客户端代理类,以便您快速构建(正确配置)客户端应用程序和测试。
在服务的 app.config 类中,添加以下内容:
还添加一个附加端点以公开服务的元数据:
现在,您可以使用“添加服务引用”添加对客户端/测试应用程序的引用:

HTH。
The short answer here is that you need to remember the ABC of
Indigo... ahem ... WCF: Address, Binding, Contract.The fact that your service's endpoints are implemented within the same physical class is irrelevant to your service's callers: To the outside world, your service is now exposed via two distinct service endpoints: IPlanning & INotification.
Modify your app.config file's endpoints to expose each service endpoint at its own address (relative to your service's base address):
Oh ... and you don't need all the REST Friendly endpoint behavior stuff - webHttpBinding already supports httpGet by default. :)
Also, I strongly encourage you to enable service metadata (esp' while developing) as this allows you to use tools to generate the client-side proxy classes to allow you to quickly build (properly configured) client apps and tests.
To your service's app.config class, add the following:
Also add an additional endpoint to expose your service's metadata:
Now you can add references to your client/test apps using "Add Service Reference":

HTH.