“多个过滤器匹配。”在WCF中为多个端点使用相同的地址时

时间:2011-12-12 15:34:02

标签: c# wcf service endpoint

因此,由于一些组织问题,我将最初的单个接口合同分成两个单独的接口合同。现在,我只有一个实现两个接口的类,我想通过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&amp; addressMatched)
System.ServiceModel.Dispatcher.EndpointDispatcherTable.Lookup(Message message, Boolean&amp; addressMatched)
System.ServiceModel.Dispatcher.ChannelHandler.GetDatagramChannel(Message message, EndpointDispatcher&amp; endpoint, Boolean&amp; 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)

我不知道如何解决这个问题。据我所知,从以下指南中,这是为多个端点使用相同类型的正确方法。有什么想法吗?

2 个答案:

答案 0 :(得分:0)

你可以使用下面的内容,看看你是否还有例外:

<service name="TravelPlannerWebService.Domain.Entity.ETravelPlanner">
        <endpoint address="" binding="webHttpBinding" bindingConfiguration="" contract="TravelPlannerWebService.Acquaintance.IPlanning" behaviorConfiguration="RESTFriendly" />
        <endpoint address="more" binding="webHttpBinding" bindingConfiguration="" contract="TravelPlannerWebService.Acquaintance.INotification" behaviorConfiguration="RESTFriendly" />
        <host>
          <baseAddresses>
            <add baseAddress="http://localhost:80" />
          </baseAddresses>
        </host>
      </service>

您不能在同一地址上侦听2个不同的端点。因此,我添加了地址属性来区分它们。

在IIS中托管时,您的网址可能如下所示:

http://localhost/ApplicationVD/PlanTrip
http://localhost/ApplicationVD/PlanTripDelayed
http://localhost/ApplicationVD/PlanTripLoc
http://localhost/ApplicationVD/More/GetInfo
http://localhost/ApplicationVD/More/RegisterRID

答案 1 :(得分:0)

这里简短的回答是你需要记住 Indigo 的ABC ......咳嗽... WCF:地址,绑定,合同。

您的服务端点在同一物理类中实现的事实与您的服务呼叫者无关:对于外部世界,您的服务现在通过两个不同的服务端点公开:IPlanning&amp; INotification。

修改app.config文件的端点,使每个服务端点在其自己的地址(相对于服务的基地址)公开:

<endpoint name ="TripPlanningEndpoint" 
    address="Planning" binding="webHttpBinding" contract="Service.IPlanning" 
    behaviorConfiguration="RESTFriendly" />

<endpoint name="TripNotificationsEndpoint" 
    address="Notifications" binding="webHttpBinding" contract="Service.INotification" 
    behaviorConfiguration="RESTFriendly" />

哦......并且您不需要所有REST Friendly端点行为的东西 - webHttpBinding默认情况下已经支持httpGet。 :)

此外,我强烈建议您启用服务元数据(特别是在开发时),因为这允许您使用工具生成客户端代理类,以便您快速构建(正确配置)客户端应用程序和测试。 / p>

在服务的app.config类中,添加以下内容:

<system.serviceModel>
    <behaviors>
     ...
        <serviceBehaviors>
            <behavior name="ServiceMetadataBehavior">
                <serviceMetadata httpGetEnabled="true"/>
            </behavior>
        </serviceBehaviors>
    </behaviors>

还要添加其他端点以公开服务的元数据:

<endpoint contract="IMetadataExchange" binding="mexHttpBinding" address="mex" />

现在,您可以使用“添加服务参考”添加对客户端/测试应用的引用: Multi-interface WCF Service - Add Reference Dialog

HTH。