如何配置具有两个端点的 WCF 服务,以便为每个端点使用不同的 ListenUri?
我有一个 WCF 服务,它使用 webHttpBinding 公开端点,并由 WPF 和 ASP.NET 应用程序使用。一切都很好。
我现在尝试从 Windows Phone (WP7) 使用该服务。但是,由于 .NET Framework 尚未完全赶上 WP7,System.ServiceModel.Web
命名空间不可用,导致 webHttpBinding
无法工作在 WP7 中。
现在,在我的服务上,如果我将 webHttpBinding
切换为 basicHttpBinding
,电话应用程序就可以工作。
不过,我不想为了使用 basicHttpBinding
而重新设计我的 WPF 和 ASP.NET 应用程序。
我了解 WCF 能够支持多个绑定,并且我尝试配置和运行该服务,以便它公开 webHttpBinding
和 basicHttpBinding
的端点。该服务似乎启动良好。然而,WPF 和ASP.NET 应用程序无法访问它。当我尝试在 WP7 应用程序中创建服务引用时,我收到以下消息:
绑定实例已关联到侦听 URI 'http://localhost:1726/GeneralService.svc'。如果两个端点想要 共享相同的 ListenUri,它们也必须共享相同的绑定对象 实例。两个冲突的端点要么在 AddServiceEndpoint() 调用,在配置文件中,或组合 AddServiceEndpoint() 和配置。
我和一位同事对 baseAddress
、address
和 listenUri
属性进行了各种更改,但没有成功。我们现在正处于反复试验的阶段,但事实证明这并不是非常有效。
<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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
只需为基本端点或 webhttp 端点指定一个值来指定地址属性,以区分其地址。例如:
应该可以解决您的问题
Just specify the address attribute with a value for either basic or webhttp endpoint that would distinguish its address. Ex:
should resolve your problem
在为第一个端点定义端点时,您指定
address=""
,而第二个端点则没有任何值(因此即使对于这个端点,我们也将地址指定为""
)因此,在这种情况下,当我们将地址指定为空时,它将采用默认基地址。
因此,请尝试为任何端点指定一些值。这样我们将为这两个端点提供不同的地址。
所以我们的新端点地址是:
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""
)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.
So our new endpoints address are:
对于 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.
我缺少的是两个端点的
protocolMapping
:What I was missing was
protocolMapping
for both endpoints: