WCF IIS托管服务由单个服务实现的多个服务契约 - 如何通过配置在端点之间共享uri

Sim*_*Fox 9 iis configuration wcf iis-7 wcf-binding

我有一组服务合同,将我的服务接口分成相关功能块.我目前正在使用单个服务类实现所有合同(可能希望稍后拆分它们,但现在单个服务类就足够了).

我试图使用配置文件配置端点(而不是通过代码).问题是我得到了一个,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>
Run Code Online (Sandbox Code Playgroud)

所以我的问题是如何在两个端点之间共享这种绑定?

这个SO问题中的评论表明我可能无法做到这一点,但我不相信这是正确的.

更新1根据这篇MS出版物,我正在做的应该没问题......

UPDATE2如果有帮助,这是svc文件内容:

<%@ ServiceHost Language="VB" Debug="true"
                Service="*********************.MidTierAccessService"
                Factory="Microsoft.ServiceModel.Web.WebServiceHost2Factory" %>
Run Code Online (Sandbox Code Playgroud)

更新3这是例外细节:

绑定实例已与侦听URI"********************"相关联.如果两个端点想要共享相同的ListenUri,则它们还必须共享相同的绑定对象实例.两个冲突的端点要么在AddServiceEndpoint()调用中,在配置文件中指定,要么在AddServiceEndpoint()和config的组合中指定.

更新4好的我以前错过了这个,说明"在为特定的.svc服务公开多个端点时,您将需要使用相对地址".造成这种情况的原因与IIS虚拟目录确定服务的基地址有关,任何人都可以更详细地解释这一点,即为什么IIS需要为每个合同进行相对寻址.

jri*_*sta 7

据我所知,我上个月一直在与WCF进行大量的工作,你不能为多个端点共享相同的URI.在WCF中,"服务"不是由合同的实现定义的,而是由合同本身定义的(也遵循WSDL和标准的SOA实践.)端点允许您通过多个协议(以及不同的地址)公开单个服务,但您不能在同一个确切的地址上共享不同的服务.逻辑上这是行不通的.

假设以下场景(这是您要完成的):

IProductService exposed @ http://localhost/service
ICategoryService exposed @ http://localhost/service
IMetadataExchange exposed @ http://localhost/service/mex
Run Code Online (Sandbox Code Playgroud)

访问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服务,需要像其他任何一样托管.