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

WCF和多个主机头

  •  10
  • Ryu  · 技术社区  · 16 年前

    我的雇主网站有多个主机名,所有主机名都在同一台服务器上,我们只是为了品牌目的显示不同的外观。

    不幸的是,在这种情况下,WCF似乎不能很好地工作。

    我试过了 overriding the default host with a custom host factory .

    这不是一个可接受的解决方案,因为它需要从所有主机工作,而不仅仅是1。

    我也看过 this blog post 但要么我不能让它工作,要么它不是要解决我的问题。

    我得到的错误是“这个集合已经包含一个带有方案http的地址”

    必须有一种配置方法,请帮助:)

    5 回复  |  直到 10 年前
        1
  •  5
  •   thaBadDawg    16 年前

    如果您不在端点中放置地址,那么它应该解析为任何服务器访问服务的地址。我使用此代码,它从IIS解析为my.local地址和my.com地址。

    <system.serviceModel>
        <services>
            <service name="ServiceName" behaviorConfiguration="ServiceName.Service1Behavior">
                <endpoint address="" binding="wsHttpBinding" contract="iServiceName">
                </endpoint>
                <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
            </service>
        </services>
        <behaviors>
            <serviceBehaviors>
                <behavior name="ServiceName.Service1Behavior">
                    <!-- To avoid disclosing metadata information, set the value below to false and remove the metadata endpoint above before deployment -->
                    <serviceMetadata httpGetEnabled="true"/>
                    <!-- To receive exception details in faults for debugging purposes, set the value below to true.  Set to false before deployment to avoid disclosing exception information -->
                    <serviceDebug includeExceptionDetailInFaults="true"/>
                </behavior>
            </serviceBehaviors>
        </behaviors>
    </system.serviceModel>
    
        2
  •  5
  •   zcrar70    15 年前

    我不认为 主机基地址 上面发布的解决方案将适用于IIS托管的网站(运营商确实提到这是为他的雇主 网站 )

    this blog post

    另外,另一个答案更进一步 塔巴达瓦格 在指定多个主机头的情况下不起作用-您只会得到op提到的错误(“此集合已经包含一个带有方案http的地址”)。

    我认为到目前为止提到的任何解决方案都不会起作用,因为它看起来不像是WCF允许单个服务可以访问来自所有站点的具有多个主机头的单个站点。对于.NET 3.5(及更低版本),我唯一能找到的解决方法是为每个主机头创建不同的协定,并使用自定义ServiceHostfactory根据指定的协定使用正确的主机头。这根本不实际。显然 .Net 4.0 will resolve this issue .

        3
  •  3
  •   struhtanov    15 年前

    我几天前遇到这个问题。事实上,我和Ryu最初在问题中描述的情况是一样的。我们为许多客户提供了一个虚拟目录,但每个客户都有自己的绑定。像“ http://company1.product.com “,” http://company2.product.com “等等。

    描述的解决方案 here 作品。但价格是多少!每次需要添加新绑定时,我们都应该更改web.config。而且web.config还应该包含绝对路径前缀 喜欢 <add prefix=”http://company1.product.com”/> .

    可以绕过第一个问题。我为WCF服务编写了自己的CustomHostfactory,在其中动态添加端点。以及我从IIS绑定中检索到的这个端点(有一种从IIS获取信息的方法)。

    以下是示例代码:

    protected override ServiceHost CreateServiceHost(Type serviceType, Uri[] baseAddresses)
    {
        var serviceHost = base.CreateServiceHost(serviceType, baseAddresses);
        var webHttpBinding = new WebHttpBinding();
        var serviceEndpoint1 = serviceHost.AddServiceEndpoint(typeof(IService), webHttpBinding,
                                                             "http://company2.product.com/WCFService/Service.svc");
    
        var serviceEndpoint2 = serviceHost.AddServiceEndpoint(typeof(IService), webHttpBinding,
                                                     "http://company1.product.com/WCFService/Service.svc");
    
        var webHttpBehavior = new WebHttpBehavior();
    
        serviceEndpoint1.Behaviors.Add(webHttpBehavior);
        serviceEndpoint2.Behaviors.Add(webHttpBehavior);
    
        return serviceHost;
    }
    

    而不是硬编码端点URL,而是从IIS中检索它们。 但当应用程序启动时,会创建一次ServiceHost。因此,如果需要添加新绑定,应该重新启动IIS。这不是我们的解决方案。

    这就是我们决定搬到ASMX的原因(如所述 here ) 然后等到框架4.0发布,在该版本中应该支持多个绑定。

        4
  •  0
  •   LMK    10 年前

    一个不涉及任何代码或配置更改的简单解决方案是在IIS中创建另一个指向相同物理目录和相同应用程序池但具有不同主机头绑定的网站。这可以对尽可能多的不同主机名进行。

        5
  •  -1
  •   Steve    16 年前

    我相信你现在已经弄明白了,不过为了好玩,我还是会在这里发帖的。

    我遇到了这个确切的问题,一直在努力解决它。最好的解决办法是 主机基地址 在您的服务定义中,它允许服务在这些多个地址下运行。要使此解决方案工作,您仍然需要重写ServiceHostfactory。既然你已经这样做了,就把它放在那里吧。

    <service behaviorConfiguration="ServiceBehaviour" name="Api.Service">
        <endpoint address="soap" binding="basicHttpBinding" contract="Api.IService" />
        <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
        <host>
          <baseAddresses>
            <add baseAddress="http://host1.com/Api" />
            <add baseAddress="http://host2.com/Api" />
          </baseAddresses>
        </host>
      </service>