如何配置具有两个端点的WCF服务,以便为每个端点使用不同的ListenUri?

时间:2012-01-12 15:11:47

标签: wcf windows-phone-7 basichttpbinding webhttpbinding

我有一个WCF服务,它使用webHttpBinding公开一个端点,并被WPF和ASP.NET应用程序使用。一切都很好。

我现在正尝试从Windows Phone(WP7)中使用该服务。但是,由于.NET Framework还没有完全赶上WP7,System.ServiceModel.Web命名空间不可用,导致webHttpBinding在WP7中不起作用。

现在,在我的服务上,如果我将webHttpBinding切换为basicHttpBinding,则电话应用程序可以正常工作。

我不想重写我的WPF和ASP.NET应用程序以使用basicHttpBinding

我知道WCF能够支持多个绑定,并且我尝试配置和运行该服务,以便它为webHttpBindingbasicHttpBinding公开端点。该服务似乎启动良好。但是,WPF& ASP.NET应用程序无法访问它。当我尝试在WP7应用程序中创建服务引用时,我收到以下消息:

  

绑定实例已与侦听URI相关联   的 'http://本地主机:1726 / GeneralService.svc'。如果两个端点想要   共享相同的ListenUri,他们还必须共享相同的绑定对象   实例。两个冲突的端点都指定在   AddServiceEndpoint()调用,配置文件或其组合   AddServiceEndpoint()和config。

我和一位同事玩过baseAddressaddresslistenUri属性的各种变化而没有任何运气。我们现在正处于试验和错误的阶段,这并没有证明是非常有效的。

<system.serviceModel>
    <serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
    <bindings>
        <basicHttpBinding>
            <binding name="generalBasic" />
        </basicHttpBinding>
        <webHttpBinding>
            <binding name="general" maxReceivedMessageSize="2147483647">
                <readerQuotas maxStringContentLength="2147483647" maxArrayLength="2147483647" />
                <security mode="None">
                    <transport clientCredentialType="None" />
                </security>
            </binding>
        </webHttpBinding>
    </bindings>
    <behaviors>
        <serviceBehaviors>
            <behavior>
                <serviceMetadata httpGetEnabled="true"/>
                <serviceDebug includeExceptionDetailInFaults="false" />
            </behavior>
        </serviceBehaviors>
        <endpointBehaviors>
            <behavior name="web">
                <webHttp />
            </behavior>
        </endpointBehaviors>
    </behaviors>
    <services>
        <service name="MyProject.GeneralService">
            <endpoint address="mex" 
                binding="mexHttpBinding"
                contract="IMetadataExchange" />
            <endpoint address="" 
                binding="basicHttpBinding" 
                bindingConfiguration="generalBasic"
                contract="MyProject.Contracts.IGeneralService" />
            <endpoint behaviorConfiguration="web" 
                binding="webHttpBinding"
                bindingConfiguration="general" 
                contract="MyProject.Contracts.IGeneralService" />
            <host>
                <baseAddresses>
                    <add baseAddress="http://localhost:1726/" />
                </baseAddresses>
            </host>
        </service>
    </services>
</system.serviceModel>

4 个答案:

答案 0 :(得分:8)

只需使用基本或webhttp端点的值指定address属性即可区分其地址。例如:

<endpoint behaviorConfiguration="web" address="rest" binding="webHttpBinding" bindingConfiguration="general" contract="MyProject.Contracts.IGeneralService" /> 

应解决您的问题

答案 1 :(得分:2)

为第一个定义端点时,您指定的是address="",第二个没有任何值(所以即使是这个,我们也会将地址设为""

<endpoint address="" 
            binding="basicHttpBinding" 
            bindingConfiguration="generalBasic"
            contract="MyProject.Contracts.IGeneralService" />
        <endpoint behaviorConfiguration="web" 
            binding="webHttpBinding"
            bindingConfiguration="general" 
            contract="MyProject.Contracts.IGeneralService" />

因此,在这种情况下,当我们将地址指定为空时,它将采用默认基址。

因此,请尝试为任何端点指定一些值。这样我们将为这两个端点提供不同的地址。

<endpoint address="" 
            binding="basicHttpBinding" 
            bindingConfiguration="generalBasic"
            contract="MyProject.Contracts.IGeneralService" />
        <endpoint behaviorConfiguration="web" address="WP7Service" 
            binding="webHttpBinding"
            bindingConfiguration="general" 
            contract="MyProject.Contracts.IGeneralService" />

所以我们的新端点地址是:

  1. 的http://本地主机:1726 / GeneralService.svc
  2. 的http://本地主机:1726 / GeneralService.svc / WP7Service

答案 2 :(得分:0)

对于WP上的使用服务,您应该使用Rest,Soap或OData端点公开您的服务。在下面的链接中,非常清楚地描述了如何为此目的公开WCF RIA:
Exposing WCF (SOAP\WSDL) Services
它对我很有用。

答案 3 :(得分:0)

两个端点我都缺少protocolMapping

<configuration>
  <!--...-->
  <system.serviceModel>
    <!--...-->
    <protocolMapping>
      <add binding="basicHttpBinding" scheme="http" bindingConfiguration="BasicHttpBindingConfiguration"/>
      <add binding="basicHttpsBinding" scheme="https" bindingConfiguration="SecureHttpBindingConfiguration"/>
    </protocolMapping>
    <bindings>
      <basicHttpBinding>
        <binding name="BasicHttpBindingConfiguration" />
        <binding name="SecureHttpBindingConfiguration" >
          <security mode="Transport">
            <transport clientCredentialType="None" proxyCredentialType="None"/>
          </security>
        </binding>
      </basicHttpBinding>
    </bindings>
    <services>
      <service name="Namespace.ServiceName">
        <endpoint address="" binding="basicHttpBinding" bindingConfiguration="BasicHttpBindingConfiguration"
          contract="Namespace.IServiceName" />
      </service>
      <service name="Namespace.ServiceName">
        <endpoint address="" binding="basicHttpsBinding" bindingConfiguration="BasicHttpsBindingConfiguration"
          contract="Namespace.IServiceName" />
      </service>
    </services>
    <!--...-->
  </system.serviceModel>
  <!--...-->
</configuration>