Beau
Beau

Reputation: 195

WCF multiple end points on IIS and connecting to them separately

Question:

is there some way to access one end point without getting the details of the other end point? That is to connect to one endpoint of a configured service without getting the details from all the end points of the service?

I have configured 2 end points, with two different interfaces, and two different bindings, using the same class.

The web service is being hosted in IIS 7.5 on a window 7 test machine

Excerpt from the web.config file:

<bindings>
  <basicHttpBinding>
     <binding name="ServerUIBinding" 
              maxReceivedMessageSize="2097152" maxBufferSize="2097152" 
              sendTimeout="00:01:00" receiveTimeout="00:01:00">
     </binding>
     <binding name="ServerLinkBinding" 
              maxReceivedMessageSize="2097152" maxBufferSize="2097152"  
              sendTimeout="00:02:00" receiveTimeout="00:02:00">
     </binding>
  </basicHttpBinding>
</bindings>
<services>
  <service name="APOServiceLibrary.ServerUI"
           behaviorConfiguration="DefaultMetaDataBehaviour">
    <endpoint name="ServerUIEndPoint"
              address="/ServerUI"
              binding="basicHttpBinding"
              bindingConfiguration="ServerUIBinding"
              contract="APOServiceLibrary.IServerUI">
    </endpoint>
    <endpoint name="ServerLinkEndPoint"
              address="/ServerLink"
              binding="basicHttpBinding"
              bindingConfiguration="ServerLinkBinding"
              contract="APOServiceLibrary.IServerLink">
    </endpoint>
    <endpoint address="mexServer"
              binding="mexHttpBinding"
              contract="IMetadataExchange">
    </endpoint>
  </service>
</services>
<behaviors>
  <serviceBehaviors>
    <behavior name="DefaultMetaDataBehaviour">
      <serviceMetadata httpGetEnabled="True"/>
      <serviceDebug includeExceptionDetailInFaults="False"/>
    </behavior>
  </serviceBehaviors>
</behaviors>

I have configured the service as follows in a ServerUI.svc file:

<%@ ServiceHost Language="C#" Debug="true" Service="APOServiceLibrary.ServerUI" %>

When I connect to the hosted site (the way I have it setup I can connect using the following URL: http://localhost/test/serverui.svc) using the WcfTestClient.exe tool, I can correctly see the breakdown of the two end points, and I can likewise see the wsdl definition if I browse to http://localhost/test/ServerUI.svc?wsdl

I've been reading here at stackoverflow that the address field in an end point (eg. address="/ServerLink") is relative to the IIS configured website and that it should be possible to connect to just one of the end points using this type of path:

http://localhost/test/ServerUI.svc/ServerLink

However, that does not seem to work with the WcfTestClient.exe tool. That is I cannot connect to http://localhost/test/ServerUI.svc/ServerLink with the tool. Nor can I browse to that site in a web browser. Additional I've tried making a new c# app and connecting to the web service using that address and it does not work. Whenever I try this is always seems to generate this type of error

Error: Cannot obtain Metadata from Cannot obtain Metadata from http://localhost/test/ServerUI.svc/ServerLink If this is a Windows (R) Communication Foundation service to which you have access, please check that you have enabled metadata publishing at the specified address.

So, back to my question, is there some way to do this? That is connect to only one of the end points and get the definition for it? Is there something different I have to do with MetadataExchange to generate data for each end point separately? Is there something in the .svc file I can configure to do so?

The reason I would like to do so is to provide some of our other teams with a "cleaner" interface with less methods, and less sensitive to large dataset timeouts (that's the extra minute timeout of ServerLink)

A solution I have considered is making a wrapper class and using that to create a separate svc file so that a completely separate URL would be used, but that seems like a poor solution.

Upvotes: 0

Views: 491

Answers (1)

mclark1129
mclark1129

Reputation: 7592

That is because the WCF test client uses the mex endpoint exposed by your service to determine all of the endpoints, and to automatically generate a client that can talk to your endpoints. You cannot point it to an individual endpoint address, because the endpoints that expose your service contracts (IServerUI and IServerLink) don't know how to describe themselves to potential clients, they only know how to accept properly formatted requests and issue properly formatted responses for their respective contracts.

The same rules will apply if you are automatically generating client code in Visual Studio using the svcutil. You will need to generate service references using the mex endpoint, and not pointing to the individual contract endpoints. The svcutil will generate client code for all endpoints in the service automatically.

When you are configuring actual clients (WPF or whatever) to talk to your service, their config will need to have a client endpoint configured for each contract that the app needs to talk to. The address for these endpoints will be the actual address of the contract's endpoint, and not the metadata endpoint (e.g. http://localhost/test/ServerUI.svc/ServerLink)

You said yourself:

When I connect to the hosted site (the way I have it setup I can connect using the following URL: http://localhost/test/serverui.svc) using the WcfTestClient.exe tool, I can correctly see the breakdown of the two end points, and I can likewise see the wsdl definition if I browse to http://localhost/test/ServerUI.svc?wsdl

This is the proper and expected behavior for the test client. Now you can issue calls to all the endpoints exposed by your service. When you use the client to make a call to one of the endpoints it will send that request to the specific address that you would expect.

Upvotes: 3

Related Questions