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

发布于 2024-12-26 07:19:37 字数 3033 浏览 2 评论 0原文

我有一个 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>

I have a WCF Service which exposes an endpoint using the webHttpBinding and is consumed by both WPF and ASP.NET applications. Everything works great.

I am now attempting to consume the service from Windows Phone (WP7). However, as the .NET Framework hasn't quite caught up to WP7 yet, the System.ServiceModel.Web namespace is unavailable with the result that the webHttpBinding doesn't work in WP7.

Now, on my service, if I switch the webHttpBinding out for a basicHttpBinding, the phone application works.

I do not want to have to rework my WPF and ASP.NET applications to use the basicHttpBinding though.

I understand that WCF is capable of supporting multiple bindings and I have attempted to configure and run the service so that it exposes endpoints for both webHttpBinding and basicHttpBinding. The service appears to start up fine. However, the WPF & ASP.NET applications are unable to access it. And when I attempt to create a Service Reference in the WP7 application I get the following message:

A binding instance has already been associated to listen URI
'http://localhost:1726/GeneralService.svc'. If two endpoints want to
share the same ListenUri, they must also share the same binding object
instance. The two conflicting endpoints were either specified in
AddServiceEndpoint() calls, in a config file, or a combination of
AddServiceEndpoint() and config.

A colleague and I have played around with a variety of changes to the baseAddress, address, and listenUri attributes without any luck. We are now at the point of just trial and error which isn't proving to be very effective.

<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>

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

允世 2025-01-02 07:19:37

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

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

应该可以解决您的问题

Just specify the address attribute with a value for either basic or webhttp endpoint that would distinguish its address. Ex:

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

should resolve your problem

作死小能手 2025-01-02 07:19:37

在为第一个端点定义端点时,您指定 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

When defining your endpoints for the first one you are specifying address="" and for second you dont have any value(So even for this one we will have address as "")

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

So in that case when we specify address as empty it will take default base address.

So try to specify some value for anyone of the endpoints. So that we will have different address for these 2 endpoints.

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

So our new endpoints address are:

  1. http://localhost:1726/GeneralService.svc
  2. http://localhost:1726/GeneralService.svc/WP7Service
完美的未来在梦里 2025-01-02 07:19:37

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

这对我来说非常有用。

For usage service on WP you should expose your service with Rest, Soap or OData endpoints. In the link below it is quite clear described how to expose WCF RIA for such purposes:
Exposing WCF (SOAP\WSDL) Services

It works great for me.

蓝色星空 2025-01-02 07:19:37

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

What I was missing was protocolMapping for both endpoints:

<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>
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文