Hosting a WCF service over TCP | Structuring Project - c#

I'm trying to develop a WCF service in the following manner:
A class library project which will have all contract and their implementations , called WcfContracts.
A WCF service library project which will have the configuration part i.e it will have only the app.config. The project will have references to the class library which is having the contract & their implementations.i.e to WcfContracts.This project is called WcfServiceHosting.
A windows service which can host the WCF service. The service will have the same app.config as the WCF service and will be used only for hosting the WCF service.I created a new app.config in the service project, and copied the contents of the app.config from WCF service library to it.
A WPF client application, which was intended to talk to the service hosted in the windows service. I was adding ServiceReference to the WCF contract.
All projects lie in the same solution.
However while doing the above I'm not able to add the service reference in the client project. If I keep the contracts & implementations in the same WCF service library everything works fine.
The following is my app.config for WCF service library:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.web>
<compilation debug="true" />
</system.web>
<system.serviceModel>
<services>
<service behaviorConfiguration="WcfServiceHosting.Service1Behavior"
name="WcfServiceHosting.CalculatorService">
<endpoint address="" binding="netTcpBinding" bindingConfiguration=""
contract="**WcfServiceHosting.ICalculatorService**">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
<endpoint address="mex" binding="mexTcpBinding" bindingConfiguration=""
contract="IMetadataExchange" />
<host>
<baseAddresses>
<add baseAddress="net.tcp://localhost:8523/CalculatorService" />
</baseAddresses>
</host>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="WcfServiceHosting.Service1Behavior">
<serviceMetadata httpGetEnabled="false" />
<serviceDebug includeExceptionDetailInFaults="false" />
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
</configuration>
Now the above works just fine because IcalculatorService and CalculatorService resides in the same assembly i.e WcfServiceHosting.
Now if I remove the ICalculatService and CalculatorService from WcfServiceHosting and add it to WcfContracts, I'm not able to add the service reference. It does not show up in the reference dialog while discovering.
The following is my modified contract:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.web>
<compilation debug="true" />
</system.web>
<system.serviceModel>
<services>
<service behaviorConfiguration="WcfServiceHosting.Service1Behavior"
name="**WcfContracts.CalculatorService**">
<endpoint address="" binding="netTcpBinding" bindingConfiguration=""
contract="WcfContracts.ICalculatorService">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
<endpoint address="mex" binding="mexTcpBinding" bindingConfiguration=""
contract="IMetadataExchange" />
<host>
<baseAddresses>
<add baseAddress="net.tcp://localhost:8523/CalculatorService" />
</baseAddresses>
</host>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="WcfServiceHosting.Service1Behavior">
<serviceMetadata httpGetEnabled="false" />
<serviceDebug includeExceptionDetailInFaults="false" />
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
</configuration>
The above does not work, can you please tell me why? I have added the necessary references and all.
Thanks,
- Mike

Add Service Reference won't be able to see any contracts that aren't hosted. You need to reference the contracts (or contain them in) a project that hosts the WCF service.
e.g. how would add references know how your CalculatorServce should be hosted (TCP, HTTP, NamedPipes, MSMQ) if a host wasn't there to include the config?

Related

there was no endpoint listening at http //localhost that could accept the message

I have two project in my machine. In first application i have created WCF service it works correct only i have tested, hosting in console application after hosting press Ctlr+F5 displaying message Host started # 13-Jan-16 12:28:01 PM...
Where as in second application i am trying to add Add Service reference showing an error....
There was an error downloading 'http://localhost:8035/_vti_bin/ListData.svc/$metadata'.
Unable to connect to the remote server
No connection could be made because the target machine actively refused it 127.0.0.1:8035
Metadata contains a reference that cannot be resolved: 'http://localhost:8035/'.
There was no endpoint listening at http://localhost:8035/ that could accept the message. This is often caused by an incorrect address or SOAP action. See InnerException, if present, for more details.
Unable to connect to the remote server
No connection could be made because the target machine actively refused it 127.0.0.1:8035
If the service is defined in the current solution, try building the solution and adding the service reference again.
App.config: host application...
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior name="mexBehaviour">
<serviceMetadata httpGetEnabled="true" />
</behavior>
</serviceBehaviors>
</behaviors>
<services>
<service name="HelloService.HelloService" behaviorConfiguration="mexBehaviour">
<endpoint address="HelloService" binding="basicHttpBinding" contract="HelloService.IHelloService">
</endpoint>
<endpoint address="HelloService" binding="netTcpBinding" contract="HelloService.IHelloService">
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
<host>
<baseAddresses>
<add baseAddress="http://localhost:8035/" />
<add baseAddress="net.tcp://localhost:8032"/>
</baseAddresses>
</host>
</service>
</services>
</system.serviceModel>
</configuration>

Hosting WCF in console application : Metadata publishing for this service is currently disabled

I have WCF application and I am hosting it locally using a console application. I added the configuration below.
Service class
namespace InboundMessage.Service;
Operator: IOperator {
}
namespace InboundMessage.Service;
IOperator {
}
App.config
<configuration>
<system.web>
<compilation debug="true">
</compilation>
</system.web>
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior name="meta">
<serviceMetadata httpGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="true"/>
</behavior>
</serviceBehaviors>
</behaviors>
<services>
<service name="InboundMessage.Service.Operator" behaviorConfiguration="meta" >
<endpoint address="basic" binding="basicHttpBinding" contract="InboundMessage.Service.IOperator"/>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
<host>
<baseAddresses>
<add baseAddress = "http://X:Port/InboundMessage.Service/"/>
</baseAddresses>
</host>
</service>
</services>
</system.serviceModel>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
</startup>
</configuration>
Host Project is a console application that is built and installed in my local machine.
config file has address to the service.
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
</startup>
<appSettings>
<add key="ServiceAddress" value="http://X:Port/InboundMessage.Service/"/>
</appSettings>
<system.webServer>
<directoryBrowse enabled="true"/>
</system.webServer>
</configuration>
I keep getting Metadata publishing for this service is currently disabled. Am I missing something in my settings. Thank you for your time.
EDIT
It seems to work only if I add the below in the Host configuration but it doesn't seem the right way to host a service.
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior name="meta">
<serviceMetadata httpGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="true"/>
</behavior>
</serviceBehaviors>
</behaviors>
<services>
<service name="InboundMessage.Service.Operator" behaviorConfiguration="meta" >
<endpoint address="basic" binding="basicHttpBinding" contract="InboundMessage.Service.IOperator"/>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
</service>
</services>
</system.serviceModel>
The configuration (WCF included) has to be in the config file of the assembly that is executed. In your case, it has to be in the config file of the console application.
It is not enough that the WCF is added to the configuration of one of the libraries that the console application uses. This it for two reasons:
Configuration of the libraries is by default not copied into the output folder when you build the main (executable) assembly.
Even if it was copied, it would have a wrong name. WCF configuration is read from the config file that has the same name as the executing assembly.
This is not specific to just WCF, it's the way .NET works.

Add service reference error after try to connect my WCF service

My WCF service app.config:
<?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="WCFServiceHosting.Injector">
<endpoint address="" binding="netTcpBinding" bindingConfiguration=""
contract="WCFServiceHosting.IInjector">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
<endpoint address="mex" binding="mexTcpBinding" bindingConfiguration=""
contract="IMetadataExchange" />
<host>
<baseAddresses>
<add baseAddress="net.tcp://0.0.0.0:8523/Injector" />
</baseAddresses>
</host>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="">
<serviceMetadata httpGetEnabled="false" />
<serviceDebug includeExceptionDetailInFaults="false" />
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
</configuration>
i installed this service on my machine and this service start successfully.
in my solution i have also winform application and after try to Add service reference an error occurs:
The URI prefix is not recognized.
Metadata contains a reference that cannot be resolved: 'net.tcp://192.168.0.199:8523/Injector'.
The socket connection was aborted. This could be caused by an error processing your message or a receive timeout being exceeded by the remote host, or an underlying network resource issue. Local socket timeout was '00:04:59.9989974'.
An existing connection was forcibly closed by the remote host
If the service is defined in the current solution, try building the solution and adding the service reference again.
i also disable my firewall and try to change ip 0.0.0.0 to my machine ip address or change it to localhost but still same error.

cosume a WCF windows service from another PC

I have created a WCF service and hosted it in a windows service. Testing this service with visual studio works fine and I can consume it. Now I have installed the service on a PC (called PC1) and using another PC (called PC2) I wish to be able to discover it and consume it. I imagine that I will have to modify the app.config file to achieve this.
Here is my current app.config, what do I need to modify to get this to work from other networked computers? I'm guessing the base address is a start?
<?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="WcfAVOLibrary.AVOs">
<endpoint address="" binding="wsDualHttpBinding" contract="WcfAVOLibrary.IAVOs">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
<host>
<baseAddresses>
<add baseAddress="http://localhost:8733/Design_Time_Addresses/WcfAVOLibrary/AVOs/" />
</baseAddresses>
</host>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior>
<!-- To avoid disclosing metadata information,
set the values below to false 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>
oh and i'm running .Net 4.5
(if the web service is not implemented, I recommend this link
http://www.codeproject.com/Articles/28693/Deploying-ASP-NET-Websites-on-IIS-7-0)
You should try to modify the web.config in this place:
<baseAddresses>
<add baseAddress="http://192.168.1.2/Design_Time_Addresses/WcfAVOLibrary/AVOs/" />
</baseAddresses>
where 192.168.1.2 is your current ip, or localhost works too, it would see like this:
<baseAddresses>
<add baseAddress="http://localhost/Design_Time_Addresses/WcfAVOLibrary/AVOs/" />
</baseAddresses>
At first place, change localhost by pc1 on base address, like
http://pc1:8733/Design_Time_Addresses/WcfAVOLibrary/AVOs/
After it, try to open the base address url from browser on pc2 (yes, never mind that it is win. service - this is your service url and should be accessible). It should be ok, you need not to continue before you get it work.
When it done - review client's config to match service address.
Was facing the same issue. Added inbound rule to open the port 8733 in Windows Firewall. It worked!

Communication between two WCF Services in selfhosting Server

In a selfhosting service as described in this MSDN article
there are two servies.
Now I want to call one from the other. One does some database related stuff and the other provides some work. I want to use the database functionality in the other service.
I tried to add a service reference as mentioned here: Stackoverflow with similar question
but I get the message: "There was an error downloading metadata from the address",
so adding a service reference is not possible.
The service on their own both are running and working, as I already use them from client applications.
This is the web.config from the service I want to use.
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.web>
<compilation debug="true" targetFramework="4.0" />
</system.web>
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior>
<serviceMetadata httpGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="true"/>
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true"/>
</system.webServer>
</configuration>
And here are parts from the App.config from my selfhosting service
<?xml version="1.0"?>
<configuration>
<system.serviceModel>
<!-- omitted lots of blocks -->
<services>
<service name="MyProject.WorkService.GeneralWorkService" behaviorConfiguration="SimpleServiceBehavior">
<host>
<baseAddresses>
<add baseAddress="http://localhost:8080/"/>
</baseAddresses>
</host>
<endpoint address="traceability" binding="basicHttpBinding" name="WorkService" contract="MyProject.Service2.Contracts.IService2"/>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
</service>
<service name="MyProject.DatabaseService.GeneralDatabaseService" behaviorConfiguration="SimpleServiceBehavior">
<host>
<baseAddresses>
<add baseAddress="http://localhost:8000/"/>
</baseAddresses>
</host>
<endpoint address="gateway" binding="basicHttpBinding" name="DatabaseService" contract="MyProject.DatabaseService.Contracts.IDatabaseService"/>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
</service>
</services>
<client>
<endpoint name="Service2EP" address="http://localhost/someWork" binding="basicHttpBinding" contract="MyProject.Service2.IService2">
</endpoint>
<endpoint name="DatabaseServiceEP" address="http://localhost/gateway" binding="basicHttpBinding" contract="MyProject.DatabaseService.IDatabaseService">
</endpoint>
</client>
</system.serviceModel>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/>
</startup>
</configuration>
-update-
I can use a browser window to see my service on
http://localhost:8000
Perhaps there is some other way to use my service. Should I use some proxy
that can be generated with svcutil?
Perhaps there are better ways. Adding the service reference seems not to work
and I cannot tell why.
Are you sure that you have the mex-endpoint configured in the config of the service you are trying to reference?
If you haven't the service will not expose the info required (WSDL) to make the service reference... .
There are at least 4 possibilities:
The metadata exchange mex endpoint is not defined
Metadata exchange is not enabled
You are using the wrong address
You are being blocked by some security setting
From There was an error downloading metadata from the address
Finally found the answer.
Had to copy the endpoints from the selfhosting app.config into the service web.config.
And from that point on, the error messages in the dialog (link "Details" at the bottom)
were helpful.
Just had to add the service behavior to the DatabaseService that I already have defined in the selfhosting app.config.
Thank you all for all your help. Will accept W1ck3dHcH's answer, as it was right, but I just did not see it.

Categories