我有一组服务合同,将我的服务接口拆分为相关功能块。我目前正在使用单个服务类实现所有合同(可能希望稍后拆分它们,但现在单个服务类就足够了。)
我正在尝试使用配置文件配置端点(而不是通过代码)。问题是我得到ServiceActivationException
,因为两个端点(每个服务合同一个端点)正在尝试监听同一个uri。异常细节说,要实现这一点,两个端点必须共享绑定对象,这是有道理但我无法弄清楚如何通过配置这样做(我没有尝试通过代码,因为我在IIS托管,但但我可以想象在代码中进行配置是一个简单的练习。
以下是我目前使用的配置(这仍然是开发人员,因此我目前不担心其中一些设置可能会暴露的安全问题等):
<system.serviceModel>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" />
<services>
<service name="CDC.WebPortal.MidTier.MidTierAccessService"
behaviorConfiguration="MidTierServiceBehaviour" >
<endpoint address=""
binding="webHttpBinding"
bindingConfiguration="RestBindingConfiguration"
contract="****************************.IProductService" />
<endpoint address=""
binding="webHttpBinding"
bindingConfiguration="RestBindingConfiguration"
contract="****************************.ICategoryService" />
<endpoint address="mex" binding="mexHttpBinding"
contract="IMetadataExchange" />
</service>
</services>
<bindings>
<webHttpBinding>
<binding name="RestBindingConfiguration"
maxReceivedMessageSize="104857600">
<readerQuotas maxStringContentLength="104857600"/>
</binding>
</webHttpBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<behavior name="MidTierServiceBehaviour">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false" />
</behavior>
</serviceBehaviors>
</behaviors>
所以我的问题是如何在两个端点之间共享这种绑定?
this SO question中的评论表明我可能无法做到这一点,但我并不认为这是正确的。
更新1 根据this MS publication我正在做的事情应该没事......
UPDATE2 以下是svc文件内容,如果它有帮助:
<%@ ServiceHost Language="VB" Debug="true"
Service="*********************.MidTierAccessService"
Factory="Microsoft.ServiceModel.Web.WebServiceHost2Factory" %>
更新3 以下是例外情况:
绑定实例已与监听URI'********************'相关联。如果 两个端点想要共享同一个ListenUri,它们也必须共享相同的绑定 对象实例。两个冲突的端点都指定在 AddServiceEndpoint()调用,配置文件或AddServiceEndpoint()的组合 和配置。
更新4 确定我之前错过了this,声明“在为特定的.svc服务公开多个端点时,您将需要使用相对地址”。造成这种情况的原因与确定服务基地址的IIS虚拟目录有关,任何人都可以更详细地解释这一点,即为什么IIS需要为每个合同进行相对寻址。
答案 0 :(得分:7)
据我所知,我上个月一直在与WCF进行大量工作,你不能为多个端点共享同一个确切的URI。在WCF中,“服务”不是由合同的实现定义的,而是由合同本身定义的(也遵循WSDL和标准的SOA实践。)端点允许您通过多个协议(以及不同的地址)公开单个服务,但您不能在同一个确切的地址上共享不同的服务。从逻辑上说这是行不通的。
假设以下场景(这是您要完成的任务):
IProductService exposed @ http://localhost/service
ICategoryService exposed @ http://localhost/service
IMetadataExchange exposed @ http://localhost/service/mex
访问MEX端点很容易......它有一个唯一的URI。但是,您如何访问IProductService或ICategoryService?没有什么可以让你区分URI以外的其他两个。 WCF没有任何东西允许它在应该转到IProductservice的消息和那些应该转到ICategoryService的消息之间进行路由。由于两者都使用相同的URI,因此确实存在冲突。必须通过唯一的URI公开每个服务合同。使用相同精确绑定的每个端点都必须使用不同的地址。
有一种方法可以实现您的需求。问题是邮件路由。 WCF本身不支持消息路由OOB,但它确实提供了实现自己的消息路由器的能力。 (或者,如果您愿意使用beta技术,.NET 4.0附带一个开箱即用的消息路由器,基于下面链接的文章,但具有改进的可配置性。)Michele Bustamante,WCF的名副其实的女巫,提供了一个完整的实现和描述消息路由的文章在以下链接:
http://msdn.microsoft.com/en-us/magazine/cc500646.aspx http://msdn.microsoft.com/en-us/magazine/cc546553.aspx
一般的想法是,您设置一个侦听单个URI的服务。此服务使用通配符分派到单个服务操作,然后确定将每个消息路由到的唯一URI。您可以按照自己的意愿进行确定,但最简单的方法是通过请求Action,假设您的两个接口IProductService和ICategoryService上的每个操作都是全局唯一的。您将获得更多服务,但是...路由器本身是一个独特的WCF服务,需要像其他任何一样托管。