因此,由于一些组织问题,我将最初的单个接口合同分成两个单独的接口合同。现在,我只有一个实现两个接口的类,我想通过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)
我不知道如何解决这个问题。据我所知,从以下指南中,这是为多个端点使用相同类型的正确方法。有什么想法吗?
答案 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" />
现在,您可以使用“添加服务参考”添加对客户端/测试应用的引用:
HTH。