代码之家  ›  专栏  ›  技术社区  ›  Steve

单个WCF服务中的多个基址

  •  8
  • Steve  · 技术社区  · 16 年前

    我有一个环境,在这个环境中,同一服务器上的多个站点将使用一个服务来进行调用。例如:

    http://domain1.com/Api/Service.svc

    http://domain2.com/Api/Service.svc

    API应用程序已在映射到同一物理目录的每个站点中设置为虚拟目录,因此源仅位于一个位置。问题是,WCF不喜欢为其服务端点提供多个基址。为了让服务工作,我必须添加一个基地址前缀过滤器:

    <serviceHostingEnvironment>      
      <baseAddressPrefixFilters>        
        <add prefix="http://domain1.com/Api" />
        <!--<add prefix="http://domain2.com/Api" />-->
      </baseAddressPrefixFilters>
    </serviceHostingEnvironment>
    

    但是,这只适用于域1,因为只允许使用一个baseAddressPrefixFilter(它们不应该称之为baseAddressPrefixFilter) S 如果你只允许一个)。我尝试构建自定义ServiceHostfactory来绕过它,但在激活过程中调用ServiceHostfactory之前,我遇到了筛选问题。

    对于如何让一个服务在这样的两个域上工作有什么想法吗?

    2 回复  |  直到 14 年前
        1
  •  5
  •   Steve    16 年前

    好吧,把整个URL放在端点地址是我没想到的,所以这让我有了新的进展。在使用自定义ServiceHostfactory之后,它适用于域1,但不适用于域2。我收到一条新的错误消息,我以前没有看到:

    “没有与给定地址匹配的协议绑定” http://domain2.com/Api/Poll.svc/soap '.协议绑定是在IIS或WAS配置中的站点级别配置的。”

    更新:

    好吧,我想出来了(终于!).I可以将主机节点添加到服务定义中,并避免在每个端点中使用绝对URL。我还删除了baseAddressPrefixFilter,但在解决方案中保留了自定义服务主机工厂。

      <service name="Poll">
        <host>
          <baseAddresses>
            <add baseAddress="http://domain1.com/Api"/>
            <add baseAddress="http://domain2.com/Api"/>
          </baseAddresses>
        </host>
        <endpoint address="soap" binding="basicHttpBinding" bindingConfiguration="soapBinding"
          contract="IPoll" />
        <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />        
      </service>
    

    我担心我必须为每个绑定的每个域编写一个端点,这将是一个需要管理的过度配置。这个解决方案很好,因为我不需要这样做,它稍微简洁一点。

    这是我的ServiceHostfactory类,仅供参考。很简单,但这是必须的。一旦您拥有了它,您还必须修改.svc文件的标记以包含工厂:factory=“api.serviceHostfactory”

       public class MyServiceHostFactory : System.ServiceModel.Activation.ServiceHostFactory
    {
        protected override ServiceHost CreateServiceHost(Type serviceType, Uri[] baseAddresses)
        {                        
            ServiceHost host;
    
            host = new ServiceHost(serviceType, baseAddresses[0]);
    
            return host;
        }
    }
    
        2
  •  1
  •   Marc Gravell    16 年前

    Irc,你 可以 有不同的前缀——但每个协议只有一个前缀——所以您可以有一个TCP前缀,也可以有一个HTTPS前缀(需要检查这个前缀)。但是,您还应该能够给出服务的完整地址,而不是使用基地址和相对部分?不过,您可能需要多个端点。