Multiple Classes Implementing Same Service Contract - wcf

I have created a WCF service in which i have one service contract and multiple services classes implementing the same contract.
Could you please tell me what to edit in the app.config and how to host this service in console app.
I have one service contract and i implemented this contract in three *.cs files in wcf.
Thanks.
here is the App.config that i have written
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.web>
<compilation debug="true" />
</system.web>
<!-- When deploying the service library project, the content of the config file must be added to the host's
app.config file. System.Configuration does not support config files for libraries. -->
<system.serviceModel>
<services>
<service name="ProductService.Service1">
<host>
<baseAddresses>
<add baseAddress = "http://localhost:8732/Design_Time_Addresses/ProductService/Service1/" />
</baseAddresses>
</host>
<!-- Service Endpoints -->
<!-- Unless fully qualified, address is relative to base address supplied above -->
<endpoint address ="" binding="wsHttpBinding" contract="ProductService.IService1">
<!--
Upon deployment, the following identity element should be removed or replaced to reflect the
identity under which the deployed service runs. If removed, WCF will infer an appropriate identity
automatically.
-->
<identity>
<dns value="localhost"/>
</identity>
</endpoint>
<!-- Metadata Endpoints -->
<!-- The Metadata Exchange endpoint is used by the service to describe itself to clients. -->
<!-- This endpoint does not use a secure binding and should be secured or removed before deployment -->
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
</service>
<service name="ProductService.RegistrationService">
<host>
<baseAddresses>
<add baseAddress="http://localhost:7777/Design_Time_Addresses/ProductService/RegistrationService/"/>
</baseAddresses>
</host>
<endpoint address="" binding="wsHttpBinding" contract="ProductService.IService1">
<identity>
<dns value ="localhost"/>
</identity>
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
</service>
<service name="ProductService.ProductService">
<host>
<baseAddresses>
<add baseAddress="http://localhost:8888/Design_Time_Addresses/ProductService/ProductService/"/>
</baseAddresses>
</host>
<endpoint address="" binding="wsHttpBinding" contract="ProductService.IService1">
<identity>
<dns value ="localhost"/>
</identity>
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
</service>
<service name="ProductService.CatogeryService">
<host>
<baseAddresses>
<add baseAddress="http://localhost:8080/Design_Time_Addresses/ProductService/CatogeryService/"/>
</baseAddresses>
</host>
<endpoint address="" binding="wsHttpBinding" contract="ProductService.IService1">
<identity>
<dns value ="localhost"/>
</identity>
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior>
<!-- To avoid disclosing metadata information,
set the value below to false and remove the metadata endpoint above before deployment -->
<serviceMetadata httpGetEnabled="True"/>
<!-- To receive exception details in faults for debugging purposes,
set the value below to true. Set to false before deployment
to avoid disclosing exception information -->
<serviceDebug includeExceptionDetailInFaults="False" />
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
</configuration>

I imagine you have defined several service operations on the service contract? What you are trying to do is not possible, nor is it desirable.
Because a logical service is associated with exactly one service contract, you cannot add more than one service for the same contract.
You can add multiple service endpoints per service contract, but not on a per operation basis. You may want to do this to offer your service across two or more different transports, for example, HTTP and HTTPS.
You can consume all the operations from a single service (you have 4 services defined, so just get rid of the last three), but I don't think that is what you want to do.
To host each service operation on a separate service endpoint, you will needs to break up your service contract into multiple contracts.
This is more desirable as it reduces coupling between your endpoints and makes it much easier to understand what is going on.

Related

WCF basicHttpsBinding warning: "is invalid according to its datatype"

I created a WCF application, starting with basicHttpBinding. In app.config, I have the following endpoint configured:
<endpoint address="" binding="basicHttpBinding" contract="JMMEcommerceService.IJMMEcommerceService">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
This builds fine. However, I want to change the protocol from HTTP to HTTPS. If I change the endpoint declaration to:
<endpoint address="" binding="basicHttpsBinding" contract="JMMEcommerceService.IJMMEcommerceService">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
(note: the only change is basicHttpBinding -> basicHttpsBinding)
I get the following warning a build time:
WCF configuration validation warning: The 'binding' attribute is invalid - The value 'basicHttpsBinding' is invalid according to its datatype 'serviceBindingType'.
Why would I get this warning? Is there something else that I need to change?
Here is the full app.config:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<appSettings>
<add key="aspnet:UseTaskFriendlySynchronizationContext" value="true" />
</appSettings>
<system.web>
<compilation debug="true" />
</system.web>
<!-- When deploying the service library project, the content of the config file must be added to the host's
app.config file. System.Configuration does not support config files for libraries. -->
<system.serviceModel>
<services>
<service name="JMMEcommerceService.JMMEcommerceService">
<endpoint address="" binding="basicHttpsBinding" contract="JMMEcommerceService.IJMMEcommerceService">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
<host>
<baseAddresses>
<add baseAddress="https://localhost:8733/Design_Time_Addresses/JMMEcommerceService/JMMEcommerceService/" />
</baseAddresses>
</host>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior>
<!-- To avoid disclosing metadata information,
set the values below to false before deployment -->
<serviceMetadata httpGetEnabled="True" httpsGetEnabled="True"/>
<!-- To receive exception details in faults for debugging purposes,
set the value below to true. Set to false before deployment
to avoid disclosing exception information -->
<serviceDebug includeExceptionDetailInFaults="True" />
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
</configuration>
The basicHttpsBinding does not appear to exist in .NET 4.0, only in 4.5. Which version of .NET are you targeting?
If you like to enable HTTPS for your service, but not for your Metadata, you have to provide another base address for your HTTP-based Metadata Exchange endpoint.
<baseAddresses>
<add baseAddress="https://localhost:8733/Design_Time_Addresses/JMMEcommerceService/JMMEcommerceService/" />
<add baseAddress="http://localhost:8734/Design_Time_Addresses/JMMEcommerceService/JMMEcommerceService/" />
</baseAddresses>
Please note, that you have to assign another port too (8734). Two protocols can not use the same port!
PS: Do not forget to assign the correct certificate to the port 8733

Adding service reference to WCF project in WinForms project - error TCP error code 10061

I have multiple WCF projects that I'm trying to reference in a WinForms project. I can see several of the projects when I attempt to add a service reference, but one is not displayed and refuses to let me add it, even if I type the address in manually. When I do that I get:
Metadata contains a reference that cannot be resolved: 'net.tcp://localhost:14007/DispatchPuller/mex'.
Could not connect to net.tcp://localhost:14007/DispatchPuller/mex. The connection attempt lasted for a time span of 00:00:01.0062012. TCP error code 10061: No connection could be made because the target machine actively refused it 127.0.0.1:14007.
No connection could be made because the target machine actively refused it 127.0.0.1:14007
As far as I can tell all the services are set up the same way. Here's two, the top of one which gives me the error:
<system.serviceModel>
<services>
<service name="PASWCFDispatchPuller.DispatchPuller" behaviorConfiguration="tcpbehaviuor">
<endpoint address="" binding="netTcpBinding" bindingConfiguration="" name="nettcpDispatchPuller" contract="PASWCFDispatchPuller.IDispatchPuller">
<identity>
<dns value="localhost"/>
</identity>
</endpoint>
<endpoint address="mex" binding="mexTcpBinding" bindingConfiguration="" name="mexDispatchPuller" contract="IMetadataExchange"/>
<host>
<baseAddresses>
<add baseAddress="net.tcp://localhost:12007/DispatchPuller"/>
</baseAddresses>
</host>
</service>
<service name="PASWCFDispatchPuller.StateUpdate" behaviorConfiguration="tcpbehaviuor">
<endpoint address="" binding="netTcpBinding" bindingConfiguration="" name="nettcpStateUpdate" contract="PASWCFDispatchPuller.IStateUpdate">
<identity>
<dns value="localhost"/>
</identity>
</endpoint>
<endpoint address="mex" binding="mexTcpBinding" bindingConfiguration="" name="mexStateUpdate" contract="IMetadataExchange"/>
<host>
<baseAddresses>
<add baseAddress="net.tcp://localhost:12007/StateUpdate"/>
</baseAddresses>
</host>
</service>
</services>
<behaviors>
<serviceBehaviors>
<!--<behavior >-->
<behavior name="tcpbehaviuor">
<!-- To avoid disclosing metadata information,
set the value below to false and remove the metadata endpoint above before deployment -->
<serviceMetadata httpGetEnabled="false"/>
<!-- To receive exception details in faults for debugging purposes,
set the value below to true. Set to false before deployment
to avoid disclosing exception information -->
<serviceDebug includeExceptionDetailInFaults="False"/>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
I have no problem adding a reference to the bottom service. Changing the port for the top one also does nothing. Any suggestions would be appreciated.

Multiple WCF service endpoints in IIS breaks wcftestclient

I'm trying to expose a WCF service through both http and net.tcp binding in IIS.
Everything seems to work as expected when I specify just the net.tcp bindings, or just the http bindings, but when I add both the wcftestclient program and all other service proxy generators fail:
Error: Cannot obtain Metadata from net.tcp://host/application/service.svc
...
Metadata Exchange Error URI: net.tcp://host/application/service.svc Metadata contains a reference that cannot be resolved: 'net.tcp://host/application/service.svc '. There was > no endpoint listening at net.tcp://host/application/service.svc that could accept the message. This is often caused by an incorrect address or SOAP action. See InnerException, if present, for more details.
My web.config looks like this:
<?xml version="1.0"?>
<configuration>
<system.serviceModel>
<services>
<service behaviorConfiguration="ServiceBehavior" name="MyServiceBehavior">
<endpoint address="mex-http" binding="mexHttpBinding" name="mex-http" contract="IMetadataExchange" />
<endpoint address="service-http" binding="basicHttpBinding" name="db-http" contract="IMyService" />
<endpoint address="mex-tcp" binding="mexTcpBinding" name="mex-http" contract="IMetadataExchange" />
<endpoint address="service-tcp" binding="netTcpBinding" name="db-http" contract="IMyService" />
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="MyServiceBehavior">
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="false"/>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
</configuration>
So, if I remove the mex-http and db-http endpoints, everything is fine. If I don't, the service is accessible over http but not over tcp. If I remove the tcp endpoints, of course the http one is still available. Any thoughts?
Edit:
Based on Marc's suggestion, I changed the relevant net.tcp endpoints to read
<endpoint name="mex-http" address="net.tcp://localhost/myservice/MyService.svc/mex" binding="mexTcpBinding" contract="IMetadataExchange" />
<endpoint name="db-http" address="net.tcp://localhost/myservice/MyService.svc" binding="netTcpBinding" contract="IMyService" />
which works as expected!
Have you checked out
How to: Host a WCF Service in WAS, and
How to: Install and Configure WCF Activation Components
Have you completed those steps to make net.tcp available in IIS / WAS?
Assuming you have - I believe hosting a net.tcp WCF service in WAS requires you to either define a net.tcp base address and/or complete addresses on the net.tcp endpoints - since those things are not defined by the IIS virtual directory.
So try:
<services>
<service behaviorConfiguration="ServiceBehavior" name="MyServiceBehavior">
...(your http stuff here)....
<endpoint name="mex-http"
address="net.tcp://YourServer:7171/NetTcpService/mex"
binding="mexTcpBinding"
contract="IMetadataExchange" />
<endpoint name="db-http"
address="net.tcp://YourServer:7171/NetTcpService/MyService"
binding="netTcpBinding"
contract="IMyService" />
</service>
</services>
or:
<services>
<service behaviorConfiguration="ServiceBehavior" name="MyServiceBehavior">
<host>
<baseAddresses>
<add baseAddress="net.tcp://YourServer:7171/NetTcpService"/>
</baseAddresses>
</host>
...(your http stuff here)....
<endpoint name="mex-http"
address="mex"
binding="mexTcpBinding"
contract="IMetadataExchange" />
<endpoint name="db-http"
address="MyService"
binding="netTcpBinding"
contract="IMyService" />
</service>
</services>

How to configure basicHttpBinding for WCF service

I have a WCF service that I'm trying to get to work with wcf, old soap and plain xml. The service is called TestService.svc and the configuration looks like this:
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior name="TestServiceBehavior">
<serviceMetadata httpGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="false"/>
</behavior>
</serviceBehaviors>
<endpointBehaviors>
<behavior name="poxBehavior">
<webHttp/>
</behavior>
</endpointBehaviors>
</behaviors>
<services>
<service behaviorConfiguration="TestServiceBehavior" name="TestService">
<endpoint address="" binding="wsHttpBinding" contract="ITestService">
<identity>
<dns value="localhost"/>
</identity>
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
<endpoint address="soap" binding="basicHttpBinding" contract="ITestService"/>
<endpoint address="xml" binding="webHttpBinding" behaviorConfiguration="poxBehavior" contract="ITestService"/>
</service>
</services>
</system.serviceModel>
I got this code from this other question:
REST / SOAP endpoints for a WCF service
Now, the XML webHttpBinding seems to work well, but the wsHttpBinding and basicHttpBinding does not work very well.
I can browser to the service using:
http://localhost:8295/WCFTest/TestService.svc
I can also use that endpoint to add a service reference in an asp.net web site project and attempt to consume the service, but when I create the client:
TestService.TestServiceClient mytest = new TestService.TestServiceClient();
It says to specify an endpoint due to multiple endpoints. I guess due to having both wsHttp and basicHttp? How do I specify the endpoint here?
Next I try to consume the basicHttpBinding endpoint by adding a Web Reference (not service reference) to a .net 2.0 web site. At this point I'm not able to add the reference and receive an error 400.
So next I remove the wsHttp binding and am able to add the web reference and consume the service via a .net 2.0 client.
How do I configure it so that I can use wsHttpBinding for clients that can consume normal WCF services, basicHttpBinding for clients that can only consume older non-WCF SOAP requests and still have webHttpBinding available for clients that want to consume plain xml?
The person who posted this link (http://www.codemeit.com/wcf/wcf-restful-pox-json-and-soap-coexist.html) appears to be correct. But since this question remains unanswered, I'll elaborate a bit.
If you haven't tried it, I will mention first that nowhere in your configuration do you specify an actual address for the client service to connect to.
<service behaviorConfiguration="TestServiceBehavior" name="TestService">
<endpoint address="" binding="wsHttpBinding" contract="ITestService">
<identity>
<dns value="localhost"/>
</identity>
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
<endpoint address="soap" binding="basicHttpBinding" contract="ITestService"/>
<endpoint address="xml" binding="webHttpBinding" behaviorConfiguration="poxBehavior" contract="ITestService"/>
</service>
Your first endpoint has
<endpoint address="" binding="wsHttpBinding" contract="ITestService">
Based on documentation on MSDN (found here) and the link above, it appears that you are missing this in your service configuration
<host>
<baseAddresses>
<!-- note, choose an available port-->
<add baseAddress="http://localhost:8295/WCFTest/TestService" />
</baseAddresses>
</host>
Adding that would make your service configuration look like this
<service behaviorConfiguration="TestServiceBehavior" name="TestService">
<host>
<baseAddresses>
<!-- note, choose an available port-->
<add baseAddress="http://localhost:81/TestService" />
</baseAddresses>
</host>
<endpoint address="" binding="wsHttpBinding" contract="ITestService">
<identity>
<dns value="localhost"/>
</identity>
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
<endpoint address="soap" binding="basicHttpBinding" contract="ITestService"/>
<endpoint address="xml" binding="webHttpBinding" behaviorConfiguration="poxBehavior" contract="ITestService"/>
</service>
Adding that section will provide the address to use, while the specific endpoints will then use addresses relative to the base address provided.

App.config in WCF Library and its Windows Service Host

I have two Services called TemplateService, TemplateReportService (both defined in one WCF Service Library) to be exposed to the client application.
And, I am trying to host these services under Windows Service.
Can anyone please guide me if App.config in Windows Service will be same as the one in WCF Library?
Here is my app.config in WCF Library:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.web>
<compilation debug="true" />
</system.web>
<system.serviceModel>
<services>
<service behaviorConfiguration="ReportingComponentLibrary.TemplateServiceBehavior"
name="ReportingComponentLibrary.TemplateService">
<endpoint address="" binding="wsHttpBinding" contract="ReportingComponentLibrary.ITemplateService" >
<identity>
<dns value="localhost" />
</identity>
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" ></endpoint>
<host>
<baseAddresses>
<add baseAddress="http://localhost:8080/ReportingComponentLibrary/TemplateService/" />
</baseAddresses>
</host>
</service>
<service behaviorConfiguration="ReportingComponentLibrary.TemplateServiceBehavior"
name="ReportingComponentLibrary.TemplateReportService">
<endpoint address="" binding="wsHttpBinding" contract="ReportingComponentLibrary.ITemplateReportService" >
<identity>
<dns value="localhost" />
</identity>
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
<host>
<baseAddresses>
<add baseAddress="http://localhost:8080/ReportingComponentLibrary/TemplateReportService/" />
</baseAddresses>
</host>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="ReportingComponentLibrary.TemplateServiceBehavior">
<serviceMetadata httpGetEnabled="True"/>
<serviceDebug includeExceptionDetailInFaults="True" />
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
</configuration>
So, the App.config in my Windows Service(Where I am hosting above two services)
will be same as above or there are only some particular sections that I need to move.
Please guide.
Thank you!
First, remove the as we talked about in your other question. Second libraries don't have their own .config files and there is no (built in) way to import certain configuration sections in .NET. So you must consolidate the configuration settings for each library into the single app.config of the Windows service.