Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do you configure a WCF service with two endpoints to use a different ListenUri for each endpoint?

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>
like image 813
Steve Elmer Avatar asked Dec 22 '22 03:12

Steve Elmer


2 Answers

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

like image 141
Rajesh Avatar answered Feb 08 '23 20:02

Rajesh


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
like image 38
Pavan Kumar Aryasomayajulu Avatar answered Feb 08 '23 20:02

Pavan Kumar Aryasomayajulu