WCF service exposing 2 endpoints on 2 different service contracts
Asked Answered
E

3

9

I have an WCF service which I am trying to configure so that it exposes 2 endpoints, refering to different functionalities, under different URLs.

What I want to have is Service1, exposing methods A, B, C, and Service2, exposing methods D, E. I want to be able to browse both localhost/WebServiceName/Service1/Service.svc and localhost/WebServiceName/Service2/Service.svc.

Other applications referencing localhost/WebServiceName/Service1/Service.svc should see only the interface containing the methods A, B and C. They should not see anything regarding Service2 interface. And for Service2 likewise.

So far I have defined two interfaces in my WCF service, I_Service1 and I_Service2.

I have added two endpoints in my web.config like so:

<endpoint address="http://localhost/WebServiceName/Service1/" binding="wsHttpBinding" contract="WebServiceName.I_Service1" bindingConfiguration="Binding1" />
<endpoint address="http://localhost/WebServiceName/Service2/" binding="wsHttpBinding" contract="WebServiceName.I_Service2" bindingConfiguration="Binding2" />  

The suggestion of using full address in the enpoint comes from here: Multiple endpoints under IIS

But still, I can't browse localhost/WebServiceName/Service1/Service.svc. I receive:

Description: HTTP 404. The resource you are looking for (or one of its dependencies) could have been removed, had its name changed, or is temporarily unavailable.  Please review the following URL and make sure that it is spelled correctly. 

I can successfully browse localhost/WebServiceName/Service.svc and the wsdl includes methods A, B, C, D, E. But this should be wrong in the behaviour I want.

Is there something that I have missed?

UPDATE: Following this article http://allen-conway-dotnet.blogspot.ro/2011/09/exposing-multiple-binding-types-for.html I created two different contract services for those endpoints. But currently I am seing only Service1 when I browse it. Service2 apparently does not exist (HTTP 404 error related issues appear).

The configuration looks like:

<services>
   <service behaviorConfiguration="WebServiceName.ServiceBehavior1" name="WebServiceName.Service1">
    <endpoint address="" binding="wsHttpBinding" bindingConfiguration="Binding1"
     contract="WebServiceName.I_Service1" />
    <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
     <host>
       <baseAddresses>
         <add baseAddress="http://localhost/WebServiceName/Service1/Service.svc" />
       </baseAddresses>
     </host>
   </service>
   <service behaviorConfiguration="WebServiceName.ServiceBehavior2" name="WebServiceName.Service2">
    <endpoint address="" binding="wsHttpBinding" bindingConfiguration="Binding1"
     contract="WebServiceName.I_Service2" />
    <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
     <host>
       <baseAddresses>
         <add baseAddress="http://localhost/WebServiceName/Service2/Service.svc" />
       </baseAddresses>
     </host>
   </service>
  </services>
Ecumenism answered 6/12, 2012 at 10:53 Comment(0)
E
3

For the moment my solution to this problem was incorporating two .svc files in my webservice to separate the two interfaces. Such, I have localhost/WebServiceName/Service1.svc and localhost/WebServiceName/Service2.svc.

With the endpoint configuration

<services>
   <service behaviorConfiguration="WebServiceName.ServiceBehavior1" name="WebServiceName.Service1">
    <endpoint address="" binding="wsHttpBinding" bindingConfiguration="Binding1"
     contract="WebServiceName.I_Service1" />
    <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
     <host>
       <baseAddresses>
         <add baseAddress="http://localhost/WebServiceName/Service1.svc" />
       </baseAddresses>
     </host>
   </service>
   <service behaviorConfiguration="WebServiceName.ServiceBehavior2" name="WebServiceName.Service2">
    <endpoint address="" binding="wsHttpBinding" bindingConfiguration="Binding2"
     contract="WebServiceName.I_Service2" />
    <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
     <host>
       <baseAddresses>
         <add baseAddress="http://localhost/WebServiceName/Service1.svc" />
       </baseAddresses>
     </host>
   </service>
  </services>

This solution is not necessary the best one (if a client really wants, it can find that this service exposes 2 different interfaces, but I can secure them with different credentials/tokens). But at the moment I will go with it.

Ecumenism answered 21/12, 2012 at 14:22 Comment(0)
R
4

The way I've always done this is as follows: set a single "base address" for the service and specify the endpoint addresses as different text to append onto that base address...

 <service name="MyNamespace.MyService">
    <endpoint address="FirstEndpointAddress" binding="netTcpBinding"
      name="FirstEndpointName"
      contract="MyNamespace.FirstEndpointContract" />
    <endpoint address="SecondEndpointAddress" binding="netTcpBinding"
      name="SecondEndpointName"
      contract="MyNamespace.SecondEndpointContract" />
    <host>
      <baseAddresses>
        <add baseAddress="net.tcp://localhost:8733/MyBaseAddress" />
      </baseAddresses>
    </host>
  </service>

So in your case the base address might be localhost/WebServiceName and the endpoint address for endpoint 1 might be Service1/Service.svc. Likewise for endpoint 2 it might be Service2/Service.svc. I can see that you've followed advice to put the full address in the endpoint address, but all I can say is I've done it this way with success.

Rubin answered 10/12, 2012 at 13:42 Comment(3)
Even with this approach, I get the HTTP 404 error for localhost:8733/MyBaseAddress/FirstEndpointName/Service.svc (althought when I try to add an service reference in a client apparently localhost:8733/MyBaseAddress/Service.svc is seen while discovering services, with both interfaces which is bad in my case). Can there be a configuration error in terms of IIS, not web.config? I tried generating two Virtual Directories for the two endpoints, but both virtual directories get binded to the first endpoint's interface.Ecumenism
Unless you've given one of your endpoints the address "FirstEndpointName/Service.svc" I wouldn't expect the address you've used to work. Remember endpoint names and endpoint addresses are different things.Rubin
The ultimate address becomes: localhost:8733/MyBaseAddress/Service.svc/FirstEndpointAddress and localhost:8733/MyBaseAddress/Service.svc/SecondEndpointAddress In the client code: var svcClient = new ServiceReference1.ServiceClient("SecondEndpointName");Anciently
E
3

For the moment my solution to this problem was incorporating two .svc files in my webservice to separate the two interfaces. Such, I have localhost/WebServiceName/Service1.svc and localhost/WebServiceName/Service2.svc.

With the endpoint configuration

<services>
   <service behaviorConfiguration="WebServiceName.ServiceBehavior1" name="WebServiceName.Service1">
    <endpoint address="" binding="wsHttpBinding" bindingConfiguration="Binding1"
     contract="WebServiceName.I_Service1" />
    <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
     <host>
       <baseAddresses>
         <add baseAddress="http://localhost/WebServiceName/Service1.svc" />
       </baseAddresses>
     </host>
   </service>
   <service behaviorConfiguration="WebServiceName.ServiceBehavior2" name="WebServiceName.Service2">
    <endpoint address="" binding="wsHttpBinding" bindingConfiguration="Binding2"
     contract="WebServiceName.I_Service2" />
    <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
     <host>
       <baseAddresses>
         <add baseAddress="http://localhost/WebServiceName/Service1.svc" />
       </baseAddresses>
     </host>
   </service>
  </services>

This solution is not necessary the best one (if a client really wants, it can find that this service exposes 2 different interfaces, but I can secure them with different credentials/tokens). But at the moment I will go with it.

Ecumenism answered 21/12, 2012 at 14:22 Comment(0)
A
1

I tried to make the thing which you described. All of this succeed. Please do'nt be angry if some of steps are obvious for you. So:

  1. Create WCF Service Application Project.
  2. Add two WCF Service items (by default will be create interface and svc file).
  3. Create Web Application project.
  4. Add two Service References (Right click on Web App Project ==> Add Service Reference) by using 'Discover' button (two web services should be visible).
  5. That's all.

By default I got the following Web.config in Web Application project:

     <system.serviceModel>
<bindings>
  <basicHttpBinding>
    <binding name="BasicHttpBinding_IService1" closeTimeout="00:01:00"
      openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
      allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"
      maxBufferSize="65536" maxBufferPoolSize="524288" maxReceivedMessageSize="65536"
      messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered"
      useDefaultWebProxy="true">
      <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
        maxBytesPerRead="4096" maxNameTableCharCount="16384" />
      <security mode="None">
        <transport clientCredentialType="None" proxyCredentialType="None"
          realm="" />
        <message clientCredentialType="UserName" algorithmSuite="Default" />
      </security>
    </binding>
    <binding name="BasicHttpBinding_IService2" closeTimeout="00:01:00"
      openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
      allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"
      maxBufferSize="65536" maxBufferPoolSize="524288" maxReceivedMessageSize="65536"
      messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered"
      useDefaultWebProxy="true">
      <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
        maxBytesPerRead="4096" maxNameTableCharCount="16384" />
      <security mode="None">
        <transport clientCredentialType="None" proxyCredentialType="None"
          realm="" />
        <message clientCredentialType="UserName" algorithmSuite="Default" />
      </security>
    </binding>
  </basicHttpBinding>
</bindings>
<client>
  <endpoint address="http://localhost:3597/Service1.svc" binding="basicHttpBinding"
    bindingConfiguration="BasicHttpBinding_IService1" contract="ServiceReference1.IService1"
    name="BasicHttpBinding_IService1" />
  <endpoint address="http://localhost:3597/Service2.svc" binding="basicHttpBinding"
    bindingConfiguration="BasicHttpBinding_IService2" contract="ServiceReference2.IService2"
    name="BasicHttpBinding_IService2" />
</client>

You can try to rebuild WCF project and Update WebReferences.

Antipole answered 6/12, 2012 at 11:17 Comment(1)
There is nothing wrong with stating obvious steps; most time they are those we forget. Nonetheless, my question is about how to configure a single Web Service with 2 endpoints, not two different Web Services. Also, the configuration part is about what should be configured in that Web Service web.config, not in the web.config or app.config of applications referencing it.Ecumenism

© 2022 - 2024 — McMap. All rights reserved.