Host HTTP WCF Service in a Windows Service - c#

I'm hosting a HTTP WCFService in a Windows Service, in local network it works perfectly, but if the client is in another network and try to connect with de public IP doesn't work.
Config file:
<?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="WCFService.ServiceBehavior">
<endpoint address="" binding="wsHttpBinding"
contract="WCFService.ServiceContract">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
<endpoint address="mex" binding="mexHttpBinding"
contract="IMetadataExchange" />
<host>
<baseAddresses>
<add baseAddress="http://localhost:80/WCFService/service/" />
</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"/>
<serviceDebug includeExceptionDetailInFaults="False" />
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
</configuration>

The service metadata publishes http://localhost:80/WCFService/service/ to the client. This URL is not accessible from outside the local host.
In order to access the service from another network using a public IP the service metadata should publish http://PUBLIC_IP_ADDRESS/WCFService/service/ to the client. This can be done dynamically depending on the URL used by the client. Just add useRequestHeadersForMetadataAddress to service behaviors.
<behaviors>
<serviceBehaviors>
<behavior name="...">
...
<useRequestHeadersForMetadataAddress />
</behavior>
</serviceBehaviors>
</behaviors>
See Auto-resolving a hostname in WCF Metadata Publishing.

I suspect that when you give a config like this:
<add baseAddress="http://localhost:80/WCFService/service/" />
It would be listening in the loopback address due to the usage of locahost. Change this to the actual public IP address (i.e., not 127.0.0.1) or Server name and check again.

Related

Cannot add endpoint for WCF service in WinForms

This is my Web.config in WCF service:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.web>
<compilation debug="true" targetFramework="4.0" />
</system.web>
<system.serviceModel>
<services>
<service name="Mobile55.Service1">
<endpoint address="../Service1.svc"
binding="webHttpBinding"
contract="Mobile55.IService1"
behaviorConfiguration="webBehaviour" />
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior>
<serviceMetadata httpGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="false"/>
</behavior>
</serviceBehaviors>
<endpointBehaviors>
<behavior name="webBehaviour">
<webHttp/>
</behavior>
</endpointBehaviors>
</behaviors>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
</system.serviceModel>
<system.webServer>
<httpProtocol>
<customHeaders>
<add name="Access-Control-Allow-Origin" value="*" />
<add name="Access-Control-Allow-Headers" value="Content-Type, Accept" />
</customHeaders>
</httpProtocol>
<modules runAllManagedModulesForAllRequests="true"/>
<directoryBrowse enabled="true"/>
</system.webServer>
</configuration>
This is the first time I am working with WCF and I cannot add an endpoint for this service in my WinForms application.
I added this service as a reference and I can access the methods, but when I Debug and try to call a method it throws an exception:
Could not find default endpoint element that references contract 'MyService.IService1' in the ServiceModel client configuration section. This might be because no configuration file was found for your application, or because no endpoint element matching this contract could be found in the client element.
My application app.config file is empty.
I tried the following answers, but didn't work for me:
Could not find default endpoint element
Could not find default endpoint element that references contract - Hosting wcf
WCF Error - Could not find default endpoint element that references contract 'UserService.UserService'
How do I add an endpoint to finally be able to use my service?
Thanks in advance.
EDIT: My app.config file:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>
<services>
<service name="Mobile55.Service1">
<endpoint address=""
binding="webHttpBinding"
contract="Mobile55.IService1"
behaviorConfiguration="webBehaviour" />
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="webBehaviour">
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
</serviceBehaviors>
</behaviors>
<client>
<endpoint address="http://localhost:1008/Service1.svc"
binding="webHttpBinding"
contract="Mobile55.IService1"
behaviorConfiguration="webBehaviour" />
</client>
</system.serviceModel>
</configuration>
Well, the error message specifically says in the client configuration section.
So the error occurs client-side, i.e. from the code where you try to invoke on your service - more is hard to tell without a proper exception/stacktrace and a complete/compilable example that exhibits the behaviour.
Anyway, your configuration file is missing the client section completely.
Add something like this:
<system.serviceModel>
<!-- ... other stuff you have ... -->
<client>
<endpoint address="../Service1.svc"
binding="webHttpBinding"
contract="Mobile55.IService1"
behaviorConfiguration="webBehaviour" />
</client>
</system.serviceModel>
Something like this should do the trick hopefully
<service name="MyService.Service1">
<endpoint address="YourEndPointHere"
binding="webHttpBinding"
contract="MyService.IService1"
behaviorConfiguration="webBehaviour" />
</service>
You can try with this
<service name="Mobile55.Service1">
<endpoint address=""
binding="webHttpBinding"
contract="Mobile55.IService1"
behaviorConfiguration="webBehaviour" />
</service>
You can call your rest service with like this
localhost:port/Service1.svc/Pathname
Here Pathname is which you mentioned in operationcontract of uritemplate.
Hope it helps!
<system.serviceModel>
<client>
<endpoint address="http://localhost:1008/Service1.svc"
binding="webHttpBinding"
bindingConfiguration="webHttpBinding_IService"
contract="Mobile55.IService1"
name="webHttpBinding_IService" />
</client>
</system.serviceModel>
----------
## Heading ##
Try....

Specifying runtime address for WCF service via config

I've created a WCF library using VS2010 C#, made reference to it from other project, everithing works fine on designtime. But on runtime, as I understand it, it uses different address. So, how can I specify it?
My App.Config looks like:
<system.web>
<compilation debug="true" />
</system.web>
<system.serviceModel>
<services>
<service name="WcfService.Service1">
<host>
<baseAddresses>
<add baseAddress = "http://localhost:8732/Design_Time_Addresses/WcfService/MyWcf/" />
</baseAddresses>
</host>
<endpoint address ="" binding="wsHttpBinding" contract="WcfService.IService1">
</endpoint>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior>
<serviceMetadata httpGetEnabled="True"/>
<serviceDebug includeExceptionDetailInFaults="False" />
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
</configuration>

Can't add WCF service reference to client project using netTcpBinding

I have a WCF service that uses NetTcpBinding and I'd like to host it in a WPF application. The service seems to start correctly, but when I'm trying to get it's metadata using 'Add service reference' in visual studio I get this exception:
The URI prefix is not recognized.
Metadata contains a reference that cannot be resolved: 'net.tcp://localhost:8000/Mandrake/mex'.
My service project's App.config file:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<appSettings>
<add key="aspnet:UseTaskFriendlySynchronizationContext" value="true" />
</appSettings>
<system.web>
<compilation debug="true" />
</system.web>
<system.serviceModel>
<services>
<service name="Mandrake.Service.OTAwareService">
<endpoint address="OTService" binding="netTcpBinding" contract="Mandrake.Service.IOTAwareService">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
<endpoint name="MEX" address="mex" binding="mexTcpBinding" contract="IMetadataExchange" />
<host>
<baseAddresses>
<add baseAddress="net.tcp://localhost:8000/Mandrake/" />
</baseAddresses>
</host>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior>
<serviceMetadata/>
<serviceDebug includeExceptionDetailInFaults="False" />
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
</configuration>
And the code in the hosting application:
Uri baseAddress = new Uri("net.tcp://localhost:8000/Mandrake");
ServiceHost host = new ServiceHost(typeof(OTAwareService), baseAddress);
try
{
host.AddServiceEndpoint(typeof(IOTAwareService), new NetTcpBinding(), "OTService");
}
catch (CommunicationException e)
{
Console.WriteLine(e.Message);
host.Abort();
}
The solutions I found to the problem were mainly about adding the 'serviceMetaData' to the service config or providing a mex endpoint. Could you suggest something?
Edit:
Final config:
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior name="NewBehavior0">
<serviceMetadata />
<serviceDebug includeExceptionDetailInFaults="True" />
</behavior>
</serviceBehaviors>
</behaviors>
<services>
<service name="Mandrake.Service.OTAwareService" behaviorConfiguration="NewBehavior0">
<host>
<baseAddresses>
<add baseAddress="net.tcp://localhost:8036/OTService"/>
</baseAddresses>
</host>
<endpoint address="" binding="netTcpBinding" name="TcpEndpoint" contract="Mandrake.Service.IOTAwareService" />
<endpoint address="mex" binding="mexTcpBinding" name="MetadataEndpoint" contract="IMetadataExchange" />
</service>
</services>
</system.serviceModel>
Hosting application:
host = new ServiceHost(typeof(OTAwareService));
host.Open();
I've managed to figure it out, after enabling the serviceDebug's includeExceptionDetailInFaults it was pretty clear.
Mandrake.Service.IOTCallback.Send operation references a message element [http://tempuri.org/:Send] that has already been exported from the Mandrake.Service.IOTAwareService.Send operation
So there was a Send(OTMessage) operation in the service contract and in the callback interface as well. A rather ugly mistake but I thought I would leave the solution here in case it helps anyone.

WCF Service Hosted in a Managed Windows Service

I followed this(http://msdn.microsoft.com/en-us/library/ms733069.aspx) link and created a service and and a service host.
I added a webform client project to the solution. In order to check that my service is receiving a request I added a log in the service.
I selected my host and client to run at the same time by setting multiple start up project.
But I am having a problem making a communication between my service and client.Am i missing something in the configuration? i don't see exception at all(even though I selected CLR and JSRuntime exception, and managed debugging assistance ).
Here is my service configuration
<?xml version="1.0"?>
<configuration>
<system.serviceModel>
<client/>
<behaviors>
<serviceBehaviors>
<behavior name="meta">
<serviceMetadata httpGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="false"/>
</behavior>
</serviceBehaviors>
</behaviors>
<services>
<service name="InboundMessage.Service.Operator" behaviorConfiguration="meta" >
<endpoint address="basic" binding="basicHttpBinding" contract="InboundMessage.Service.IOperator" name="basic"/>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
<!--<endpoint address="" binding="wsHttpBinding" contract="IMetadataExchange" name="Ws" />-->
<host>
<baseAddresses>
<add baseAddress = "http://IP/InboundMessage.Service/"/>
</baseAddresses>
</host>
</service>
</services>
<bindings>
<basicHttpBinding>
<binding name="InboundMessage.Service.Operator"/>
</basicHttpBinding>
</bindings>
</system.serviceModel>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
</startup>
</configuration>
Service Host:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior name="meta">
<serviceMetadata httpGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="false"/>
</behavior>
</serviceBehaviors>
</behaviors>
<diagnostics performanceCounters="ServiceOnly" />
<services>
<service name="InboundMessage.Service.Operator" behaviorConfiguration="meta">
<endpoint address="basic" binding="basicHttpBinding" contract="InboundMessage.Service.IOperator" name="basic"/>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
<!--<endpoint address="" binding="wsHttpBinding" contract="IMetadataExchange" />-->
</service>
</services>
</system.serviceModel>
<system.web>
<compilation
debug="true" >
</compilation>
</system.web>
<system.webServer>
<directoryBrowse enabled="true"/>
</system.webServer>
</configuration>
a windowform Client configuration:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
</configSections>
<system.web>
<compilation debug="true"></compilation>
</system.web>
<system.serviceModel>
<services>
<service behaviorConfiguration="meta" name="InboundMessage.Service.Operator">
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
<host>
<baseAddresses>
<add baseAddress="http://IP/InboundMessage.Service/"/>
</baseAddresses>
</host>
</service>
</services>
<bindings>
<basicHttpBinding>
<binding name="InboundMessage.Service.Operator"/>
</basicHttpBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<behavior name="meta">
<serviceMetadata httpGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="false"/>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
</configuration>
EDIT:
Used Tim's comment to install the service but I am having problem installing it.
I opened another question thanks Tim i am having problem installing the service on my local machine. I opened another question :Unable to install service using sc command
A few of things come to mind.
First (I'm not 100% sure, but this is based on my experiences) you can't run a Windows Service as a Windows Service through Visual Studio. You need to build the project and then install it, as directed on the page you linked to.
Secondly, you only need two configuration files, not three - one for the Windows Service (which is where the configuration for the service goes) and one for the client. I'm not sure what role you have (or believe you have) for the service host config file.
Third, your client config has entries for a service in the <system.serviceModel> section - you only need those if your client is also hosting a service, which doesn't appear to be the case in the question you've asked. You should remove the <services> section and add a <client> section, like this:
<client>
<endpoint address="http://IP/InboundMessage.Service"
binding="basicHttpBinding"
bindingConfiguration="InboundMessage.Service.Operator"
contract="InboundMessage.Service.IOperator" />
</client>
Note that I used the bindingConfiguration attribute above - without that, your client will use the default basicHttpBinding (which in your case won't matter because you didn't set anything other than the name, but if you had set non-default values you would want to tell the client which binding configuration to use).
In reality the simplest way (to get started) would be to build the Windows Service, install it and start it, and then add a service reference to it in your client (WinForm) application. That will generate everything you need and you can take a look at the config file to see the settings you need.

Problems accessing WCF service via the web

Thanks to stackoverflow (mostly), I have created a WCF service that is able to pull data from our ms sql database and relay it back in a json format. The service works as expected locally and on its home server within our network. However, I can't seem to access the service when outside the network.
Are there additional parameters needed in the code to accommodate being published over the web or is it possibly just a host setup and has nothing to do with WCF or the service?
The server is 2008 R2 & IIS 7.5 which is currently hosting a dozen or so of our websites. We have setup a port for the service as well.
This is the web.config file I am using:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.web>
<customErrors mode="Off" />
<compilation debug="true" targetFramework="4.0">
<assemblies>
<add assembly="System.Data.Entity, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
</assemblies>
</compilation>
</system.web>
<system.serviceModel>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true">
</serviceHostingEnvironment>
<services>
<service behaviorConfiguration="SrvcBehavior" name="Service.svc">
<endpoint address="JSON" behaviorConfiguration="JSONEndpointBehavior" binding="webHttpBinding" bindingConfiguration="" name="RESTEP" contract="Service.Isvc" />
<endpoint address="SOAP" binding="basicHttpBinding" name="Basic" contract="Service.Isvc" />
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
</service>
</services>
<behaviors>
<endpointBehaviors>
<behavior name="JSONEndpointBehavior">
<webHttp />
</behavior>
</endpointBehaviors>
<serviceBehaviors>
<behavior name="SrvcBehavior">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug />
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
<connectionStrings>
<add name="conn" connectionString="server=SERVER-DATABASE\SQL2005;database=myDatabase;uid=USERID;password=USERPASSWORD;" />
</connectionStrings>
</configuration>

Categories