【问题标题】:How do you configure a WCF service with two endpoints to use a different ListenUri for each endpoint?如何配置具有两个终结点的 WCF 服务以对每个终结点使用不同的 ListenUri?
【发布时间】:2012-02-08 20:59:51
【问题描述】:

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

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

现在,在我的服务中,如果我将webHttpBinding 换成basicHttpBinding,电话应用程序就可以工作了。

我不想为了使用basicHttpBinding 而重新设计我的 WPF 和 ASP.NET 应用程序。

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

绑定实例已经关联到监听 URI 'http://localhost:1726/GeneralService.svc'。如果两个端点想要 共享同一个 ListenUri,它们也必须共享同一个绑定对象 实例。两个冲突的端点要么在 AddServiceEndpoint() 调用,在配置文件中,或组合 AddServiceEndpoint() 和配置。

我和一位同事对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>

【问题讨论】:

  • 只需使用基本或 webhttp 端点的值指定地址属性,以区分其地址。例如: 应该可以解决您的问题
  • 嗯...有趣,我之前尝试过,但没有成功。 (也许我添加了设置我的basicHttpBinding而不是我的webHttpBinding的地址属性)。不过,这一次,正如您所建议的,我设置了 webHttpBinding 的地址属性,并且 WP7 应用程序连接良好。将新值附加到我的 WPF 和 MVC 客户端应用程序的地址属性后,一切似乎都像魅力一样工作。发表您的评论作为答案,我会给您。谢谢:-)

标签: wcf windows-phone-7 basichttpbinding webhttpbinding


【解决方案1】:

我缺少的是两个端点的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>

【讨论】:

    【解决方案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://localhost:1726/GeneralService.svc
    2. http://localhost:1726/GeneralService.svc/WP7Service

    【讨论】:

    • 在为 json 工作时,我没有输入地址就完成了
    • 但是是的,要区分 xml 和 json 端点,您必须放入一个愚蠢的地址属性,而不是通过请求中的内容类型来计算它。因此,基本上,如果您不破解 WCF 来检查请求中的内容类型并在拦截呼叫时执行您自己的自定义代码,那么您就不能同时为 REST 提供 xml 和 json 端点。或者您必须在 url 中放置一个 /json/ 并指定一个地址 =“json” 以便您能够在 WCF 中提供 json 和 xml endoints 我猜。
    【解决方案3】:

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

    【讨论】:

      【解决方案4】:

      只需为基本或 webhttp 端点指定地址属性值,以区分其地址。例如:

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

      应该可以解决你的问题

      【讨论】:

      • @CoffeeAddict 内容类型决定了您的响应是 Json 还是 XML。 address 属性是为了区分每个端点使用哪个绑定,2 个端点不能有相同的地址
      • 是不是说当你要发送请求时,你必须将请求发布到后缀为 .svc/web 的地址,还是仍然可以使用 .svc 地址?
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-03-13
      • 2019-03-09
      • 1970-01-01
      • 1970-01-01
      • 2012-01-16
      • 1970-01-01
      • 2011-01-04
      相关资源
      最近更新 更多