WCF和多个主机标头

时间:2009-01-07 22:17:10

标签: c# wcf iis iis-6

我的雇主网站有多个主机名,所有主机名都在同一台服务器上,我们只是展示不同的皮肤用于品牌推广。

不幸的是,WCF似乎在这种情况下效果不佳。

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

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

我也看过this blog post,但我要么无法解决问题,要么无法解决我的问题。

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

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

5 个答案:

答案 0 :(得分:5)

如果您没有在端点中放置一个地址,那么它应该解析为任何服务器命中该服务。我使用这段代码,它解析了我的.local地址和IIS中的.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>

答案 1 :(得分:5)

我认为上面发布的主机基地址解决方案不适用于IIS托管网站(OP确实提到这是针对其雇主的网站

请参阅this blog post

另外, thaBadDawg 的另一个答案将无法在指定多个主机标头的情况下工作 - 您只会获得OP提到的错误(“此集合已包含一个地址方案http“。)

我认为到目前为止提到的任何解决方案都不会起作用,因为看起来WCF不允许单个站点访问单个服务,而且所有站点都有多个主机头。我能为.Net 3.5(及其下)找到的唯一解决方法是为每个主机头创建不同的合同,并使用自定义ServiceHostFactory根据指定的合同使用正确的主机头。这根本不实用。显然是.Net 4.0 will resolve this issue

答案 2 :(得分:3)

几天前我遇到了这个问题。实际上我和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;
}

而不是硬编码端点网址,你可以从IIS中检索它们。 但ServiceHost是在应用程序启动时创建的。因此,如果您需要添加新绑定,则应重新启动IIS。这不是我们的解决方案。

这就是为什么我们决定转向asmx(就像描述here)。 等到Framework 4.0发布,应该支持多个绑定。

答案 3 :(得分:0)

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

答案 4 :(得分:-1)

我相信你现在已经知道了,但为了好玩,我会在这里发布。

我遇到了这个确切的问题,并且花了很多时间试图解决这个问题。最佳解决方案是将主机基地址放在服务定义中,这样服务就可以在这些多个地址下运行。要使此解决方案起作用,您仍需要覆盖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>