I am trying to host a WCF service on a windows 2008 R2 server as a windows service. I followed the directions provided by msdn (found here). Everything works fine as long as everything is part of the same solution in visual studio. However, I tried creating a client in a different solution (on the same machine) and it can't find the service. I get an 'Add Service Reference Error' shown below.
My goal is to be able to access the wcf service remotely, but I can't seem to even access it locally unless the client was created within the same client. Is there any guides, tutorials, or helpful hints that anyone can give me to get this to work?
Update:
It seems that even though the windows service is running, the WCF service doesn't seem to be listening to any ports. Which would suggest that it isn't running. This also explains why everyone's first thought I didn't have the service running. I had assumed that since the windows service was running and that the same solution client worked, that the WCF service was working as well. Turns out that Visual Studio was starting up a WCF service whenever I ran the same solution client.
So, why isn't the windows service starting the WCF service? Any ideas?
It turns out that there was a problem with the tutorial provided by MSDN (provided in the question above). They named both the windows service and the WCF service Service1 which is the default name for both of them.
The windows service was suppose to start the WCF service, however, it was actually trying to start itself again because both services had the same name.
myServiceHost = new ServiceHost(typeof(Service1));
To fix this problem, you can rename one of the services or fully qualify the WCF service when referenced in the windows service.
myServiceHost = new ServiceHost(typeof(WcfServiceLibrary1.Service1));
The funny thing is that the code provided still looks like it works because Visual Studio is smart enough to notice that the WCF service isn't running and it starts an instance up behind the scenes.
It was a simple bug to fix, but because Visual Studio was hiding the problem from me, I don't think I would have found it without the help from Espen Burud.
There are two ways for Add Service Reference to learn about a service:
Discover button: searches the projects in the current solution.
Go button: connects to the service in the Address box and retrieves the metadata.
You need to actually have the service running before you click Go.
EDIT
I just noticed from your screenshot that you're trying to connect to a net.tcp URL. I think it's more common to use http for MEX. Your app.config would look something like:
<services>
<service behaviorConfiguration="WcfServiceLibrary1.Service1Behavior"
name="WcfServiceLibrary1.Service1">
<endpoint address="" binding="netTcpBinding" bindingConfiguration=""
contract="WcfServiceLibrary1.IService1">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
<endpoint address="mex" binding="mexTcpBinding" bindingConfiguration=""
contract="IMetadataExchange" />
<host>
<baseAddresses>
<add baseAddress="net.tcp://localhost:8523/Service1" />
<add baseAddress="http://localhost:8524/Service1" />
</baseAddresses>
</host>
</service>
</services>
Note the different port number for the http base address. You would then use "http://localhost:8524/Service1" in the Add Service Reference tool. You should also be able to connect to it with your web browser.
To allow metadata exchange via http GET (e.g. from a browser), you also need to enable it via a behavior:
<behaviors>
<serviceBehaviors>
<behavior>
<serviceMetadata httpGetEnabled="True"/>
</behavior>
</serviceBehaviors>
</behaviors>
I'm not sure if the Add Service Reference tool cares about that.
Even if you don't want to allow http get access (httpGetEnabled="False"), you still need to include this behavior to enable MEX (unless you're adding it programatically).
I have tested the MSDN article in the and it works without modifications. If the firewall is enabled on the server, I think you will need to add some rules for your service.
To verify that the service are listening on the correct tcp port, you can use command: netstat -a. If the service are listening on the correct port, this command will return:
Proto Local Address Foreign Address State
TCP 0.0.0.0:8523 machinename:0 LISTENING
I managed to figure out the issue. My service didn't know about the endpoints because I hadn't copied the service configuration from the app.config in the WCF project into the app.config of the actual windows service. Once I did that it functioned correctly.
This was not made clear in the original MSDN article which I had also followed although it is mentioned in a comment in the WCF app.config.
Related
I am trying to host a WCF Service Library on IIS 10, with a self signed SSL.
To Obtain Minimum Complete Verifiable Example, Open Visual studio 2017
New>Project>C#>Web>WCFLibrary With this you will get a simple code that has one operation contract which takes an integer and returns a string.
Now I am trying to host this on IIS with Self Signed SSL (Mine has more operation contract but this will do).
What I have tried so far.
Now the next part is hosting it on IIS, so I created the SVC file
My SVC file contains ->
<%# ServiceHost Language = "C#" Debug = "true" Service = "WcfServiceLibrary2.Service1" %>
Then all the tutorials that I can find edit Web.Config, which is unavailable in Visual Studio 2017, so I tried two things
1. Created a Web.Config file and added the configurations
2. Published the website and then obtained Web.Config which did not require any changes
Then I went on to IIS (as administrator) and added a new website
Then while trying to browse, to see the message that IIS service is hosted I got this error "Cannot read configuration file" To Solve this I followed success.trendmicro.com/…
Now that error is gone but now I am getting
To solve this I Followed
IIS - 401.3 - Unauthorized But this lead to the browser letting me browse the directories rather than giving the message that a Service has been created.
Any Idea what I am missing here?
Definitely I am missing something major here as I have failed to host it on HTTP itself, All the tutorials I find online have a file Web.Config and not App.config, I am looking for an example (preferably with Images) that demonstrate it just with this small example.
I know this doesn't follow all SO guidelines on asking questions, but I have failed to articulate it into a question that does.
Edit
As per LexLi's advice that it may already be hosted, I went and tried to consume it using svcutil which gave me the error
WS-Metadata Exchange Error
URI: http://localhost/Service1.svc
Metadata contains a reference that cannot be resolved: 'http://localhost/Service1.svc'.
The remote server returned an unexpected response: (405) Method Not Allowed.
The remote server returned an error: (405) Method Not Allowed.
HTTP GET Error
URI: http://localhost/Service1.svc
There was an error downloading 'http://localhost/Service1.svc'.
The request failed with HTTP status 404: Not Found.
The Url is correct because I obtained it by using the browse functionality from IIS.
First, please don’t set the IIS physic path to desktop, which will cause the permission problem. we could set the IIS site physical path to the folder under C partition.
Second, please read the following link, which mainly indicates that WCF service library project could not published directly to IIS since its Appconfig could not be recognized by IIS unless additional Webconfig is added manually in the root directory of the web site.
https://learn.microsoft.com/en-us/dotnet/framework/wcf/deploying-a-wcf-library-project
Generally speaking, we use the WCF service project template which contains an auto-generated Webconfig file instead of WCF service library project template, since it is generally used as a class library.
By default, the service is hosted with BasicHttpBinding, it depends on the following tag.
<protocolMapping>
<add binding="basicHttpBinding" scheme="http" />
</protocolMapping>
The service could also be configured manually by the following ways. These two ways configuration file is equivalent.
<system.serviceModel>
<services>
<service name="WcfService1.Service1" behaviorConfiguration="mybehavior">
<endpoint address="" binding="basicHttpBinding" contract="WcfService1.IService1" bindingConfiguration="mybinding"></endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"></endpoint>
</service>
</services>
<bindings>
<basicHttpBinding>
<binding name="mybinding">
<security mode="None">
</security>
</binding>
</basicHttpBinding>
</bindings>
It is unnecessary to assign the service endpoing address in the webconfig. It should be completed in the IIS site binding module.
WCF System.ServiceModel.EndpointNotFoundException
At last, we could host the service over https by adding an additional service endpoint, refer to the following configuration(simplified configuration).
<protocolMapping>
<add binding="basicHttpBinding" scheme="http"/>
<add binding="basicHttpsBinding" scheme="https" />
</protocolMapping>
then add the https protocol in IIS site binding module.
Configuring Web.config to publish WCF Service
https://learn.microsoft.com/en-us/dotnet/framework/wcf/feature-details/how-to-configure-an-iis-hosted-wcf-service-with-ssl
Feel free to let me know if there is anything I can help with.
First Credit where credit is due, many of the issues I was pointed in the right direction by multiple SO users to name a few would be: Mikael bolinder, Abraham Qian, Lex Li, the wonderful people in the C# chat room and a co-worker of mine(Doesn't have an account on SO as of writing this answer), In this answer I plan to cover everything you might need to host a WCF Library in IIS Server using HTTPS security.
Tools I used:
Visual Studio 2017 professional
IIS 10 (Comes with windows 10 but has to be activated in windows features ) (See below)
First:
Make sure you have all the components you will need from visual studio installed.
Windows -> .Net Desktop Development
Windows -> Universal Windows platfor development
Web & Cloud -> ASP.NET and web development
In this list and among other list that will come, some extra components may be included, the reason for that is I installed them and couldn't verify one way or the another if they are absolutely necessary.
Now, let's add the windows features necessary. Control Panel -> Programs -> Turn Windows features on or off
Make sure to go into WCF Services and check HTTP Activation, don't be fooled by the square block (One of my mistakes)
Now let's get to creating the Service. Open Visual Studio File -> New -> Project -> Visual C# -> Web -> WCF -> WCF Service Library This generates the MCVE that you are trying to host
Now you have to link it with a website in order to generate the Web.Config file along with the SVC file, to do that, On Solutions Explorer, right click on your solution, Add-> New Website.
Now in the web.config file add
<system.serviceModel>
<services>
<service name="WcfServiceLibrary4.Service1"> <!-- Change the library name as per your need -->
<endpoint address=""
binding="wsHttpBinding"
bindingConfiguration="secureHttpBinding"
contract="WcfServiceLibrary4.IService1"/> <!-- Change the library name as per your need -->
<endpoint address="mex"
binding="mexHttpsBinding"
contract="IMetadataExchange" />
</service>
</services>
<bindings>
<basicHttpBinding>
<binding name="secureHttpBinding">
<security mode="Transport">
<transport clientCredentialType="None"/>
</security>
</binding>
</basicHttpBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<behavior>
<!-- To avoid disclosing metadata information, set the value below to false and remove the metadata endpoint above before deployment -->
<serviceMetadata 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="false"/>
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
</system.serviceModel>
Next add reference to service on the website
Discover services and add the service you have created. Now Build your solution and publish it. **Careful Don't publish the solution in a user Directory like Desktop or documents or else ACL permissions will give you a headache, rather publish it directly in a directory in Drive.
Now Hosting time
First lets open IIS (Always as admin) and create a new certificate.
On the server go to the IIS part and Select Server Certificates, then click create new certificate on the right end.
Now create a new website from the left menu
Make sure to switch to https and select your certificate here, Now to verify that your service is created you will need to browse your websites svc file created, sadly at this point you will get an error saying Server Error in '/' Application.
Could not find a base address that matches scheme http for the endpoint with binding BasicHttpBinding. Registered base address schemes are [https]. I was unable to find the cause of the error, but I was able to find a bypass of it,
Steps to bypass this error -> Select you website from the menu on the left, on the menu at the right click bindings and also add an HTTP binding, with a different port.
After this you will be able to browse the HTTPS version of your svc file.
Now if you browse the HTTPS link you get the message that the service is created
Now you can go Ahead and create an application that consumes this service.
What lies ahead
I will try to find a way to do this without adding an additional binding
The Second goal would be to achieve this without adding the extra website.
If and when I achieve these I will update, however these are not my priority right now and may not be added for quite a while, if anything didn't make sense, or you have any ideas of improvement comment below.
In short here are the steps :
Create Self-Signed Certificate
Add SSL Binding
Configure Virtual Directory for SSL
Configure WCF Service for HTTP Transport Security
This link is more in depth : https://learn.microsoft.com/en-us/dotnet/framework/wcf/feature-details/how-to-configure-an-iis-hosted-wcf-service-with-ssl
I'm getting an error when I try to run my WCF Service on IIS instead of ASP.NET Development Server.
Clarification: I don't get an error when I run the WCF Service when using a Windows Service or ASP.NET Development Server. ONLY IIS is the problem.
I'm using a console app to test the service. I've never had problems with the service until i tried using the IIS port.
Here is my app.config file of the console app. The top address and port number is the ASP.NET Dev Server port. The second one is the IIS port.
The following is my App.config file. The top one IIS port. The active one is the ASP.NET Development Server port. When I run the ASP.NET port, I get no errors. When I run the IIS port, I get an error. (Also I have about 4 ASP.NET ports appearing on my Taskbar. I don't know why.)
My App.config file looks like this:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>
<bindings>
<wsHttpBinding>
<binding name="WSHttpBinding_IWebService" />
</wsHttpBinding>
</bindings>
<client>
<!-- <endpoint address="http://localhost:9876/Service.svc" binding="wsHttpBinding"-->
<endpoint address="http://localhost:5182/Service.svc" binding="wsHttpBinding"
bindingConfiguration="WSHttpBinding_IWebService"
contract="MyWCF_ServiceReference.IWebService"
name="WSHttpBinding_IWebService">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
</client>
</system.serviceModel>
</configuration>
Here are some images.
This is the error message that I'm getting.
Is there a reason why the address below is different from the previous ones?
http:// localhost:8732 /Design_Time_Addresses/WCFServiceLibrary/WebService/mex
This is where it is crashing for some unknown reason. Its worth noting that part of the service works. Its only when it get to ValidPerson that it crashes.
(This also doesn't happen when using the ASP.NET Development Server port 5182. Only when using IIS port 9876)
This shows that at the WCF Service itself, the ValidPerson is actually working.
Here is the conf file its running on.
I hope you guys can help me. It must be something simple.
Ok, i wasn't asking the right question although i was learning as I went.
I need to make sure the address in the config file matched either the ASP.NET development server's address (which is mostly likely the default) or change it to the IIS address which would require me to check where the WSDL was being hosted adn use that address instead of the default one. Or use the addrress assigned to my Windows Service which i could find by opening up the project file and seeing which number and address was assigned to it.
The real problem was that my Application Pool account in SQL Server needed to be set to a role of db_owner. Then all my problems went away (once i got it on the right ports with the right addresses.)
I've been battling with this for days, literally going through a hundred articles giving partial guidelines on how to set up a WCF TCP based service in a web application. If someone can help me, I will make this question into a complete guideline.
Current status
The net.tcp connection works on my development machine. It also works locally after being deployed to a Windows Server 2008 R2. However, it doesn't work remotely, even though it's possible to telnet to port 808 on the server remotely. Scroll to the bottom of the question for details. Please help if you can.
I will create a new question for this detail and update this question with the answer if I get a result out of it.
Code
I created ServerHubService.svc with the following content:
namespace Manage.SignalR
{
[ServiceContract]
public class ServerHubService
{
[OperationContract]
public void UpdateServerStatus(string serverStatus)
{
// Do something
}
}
}
Configuration of the application hosting the service
Following an online tutorial, I added the following to my Web.config (I tried MANY different variations). This is the Web.config of the web application hosting the service that I later want to connect to with TCP.
<configuration>
<system.serviceModel>
<services>
<service behaviorConfiguration="ServerHubBehavior"
name="Manage.SignalR.ServerHubService">
<endpoint address=""
binding="netTcpBinding"
bindingConfiguration="portSharingBinding"
name="MyServiceEndpoint"
contract="Manage.SignalR.ServerHubService">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
<endpoint address="mex"
binding="mexTcpBinding"
bindingConfiguration=""
name="MyServiceMexTcpBidingEndpoint"
contract="IMetadataExchange" />
<host>
<baseAddresses>
<add baseAddress="net.tcp://test.mydomain.com:808/SignalR/ServerHubService.svc" />
</baseAddresses>
</host>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="ServerHubBehavior">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false" />
</behavior>
</serviceBehaviors>
</behaviors>
<bindings>
<netTcpBinding>
<binding name="portSharingBinding" portSharingEnabled="true"/>
</netTcpBinding>
</bindings>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true"
minFreeMemoryPercentageToActivateService="0" multipleSiteBindingsEnabled="true" />
</system.serviceModel>
</configuration>
httpGetEnabled="true" is important because otherwise you cannot create a service reference to the service.
Configuration of the server where the web application is running
I am setting this up on my development machine which has IIS 7.5
I read that IIS Express (built into Visual Studio) doesn't support net.tcp, so I set up a new website in IIS 7.5 using .NET 4.5 and that has a net.tcp binding
I also went to Advanced Settings for the website and set Enabled Protocols to http,net.tcp
I ensured that the Windows Feature Non-HTTP Activation is enabled (and restarted). It's a Windows Feature so look for "Turn Windows features on or off" to find this.
Confirming the web application is running
The website works fine for the rest of the web application. I set up test.mydomain.com to point to 127.0.0.1 in my hosts file. I can even visit http://test.mydomain.com/SignalR/ServerHubService.svc and it will show me a nice auto generated page from .NET, explaining how to use this service.
So far so good.
The page generated by .NET tells me to use this address to generate a connection to my service:
net.tcp://computername/SignalR/ServerHubService.svc/mex
Trying to connect to the service as a client
If you do not remember to set httpGetEnabled="true" you will get an error when trying to create a service reference to it. If you use the WCF Test Client (also a tool included in Visual Studio) and didn't set httpGetEnabled, you will get an error like the following:
Error: Cannot obtain Metadata from
net.tcp://computername/SignalR/ServerHubService.svc/mex
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. For help enabling metadata publishing, please
refer to the MSDN documentation at
http://go.microsoft.com/fwlink/?LinkId=65455.WS-Metadata
Exchange Error URI:
net.tcp://computername/SignalR/ServerHubService.svc/mex Metadata
contains a reference that cannot be resolved:
'net.tcp://computername/SignalR/ServerHubService.svc/mex'. Could not
connect to net.tcp://computername/SignalR/ServerHubService.svc/mex.
The connection attempt lasted for a time span of 00:00:04.0032289.
TCP error code 10061: No connection could be made because the target
machine actively refused it [2001:0:4137:9e76:c81:a4c:a547:b2fd]:808.
No connection could be made because the target machine actively
refused it [2001:0:4137:9e76:c81:a4c:a547:b2fd]:808
However, if you've done everything as above, you should be able to add a reference to the service.
Calling methods in the service
When trying to call a simple Hello World method in the service from the WCF Test Client, it returns the following error:
Could not connect to
net.tcp://computername/SignalR/ServerHubService.svc. The connection
attempt lasted for a time span of 00:00:04.0002288. TCP error code
10061: No connection could be made because the target machine actively
refused it.
This is inner stacktrace that is included in with the error:
No connection could be made because the target machine actively
refused it [2001:0:5ef5:79fb:3884:a:a547:b2fd]:808 at
System.Net.Sockets.Socket.DoConnect(EndPoint endPointSnapshot,
SocketAddress socketAddress) at
System.Net.Sockets.Socket.Connect(EndPoint remoteEP) at
System.ServiceModel.Channels.SocketConnectionInitiator.Connect(Uri
uri, TimeSpan timeout)
If you use netstat -an |find /i "listening" to see that nothing is listening on port 808, it's probably because the Net.Tcp Listener Adapter service is not running.
Confirmation
The call goes through now, but some confirmation is needed before it can be declared a success. I need to confirm that this is in fact net.tcp call on port 808 and not actually a call on the http endpoint. I am trying to do this with Wireshark, but it doesn't show up, probably because it's a call happening from and to my local machine.
Deployment
The last challenge to conquer would be to deploy this on a web server, ensuring that what works on the development machine, also works on the web server.
It doesn't work after publish to a Windows Server 2008 R2. It gives the common SocketException: An existing connection was forcibly closed by the remote host.
It works well locally on the server, but it doesn't work remotely.
Here is the checklist used to check the server:
Is the Net.Tcp Listener Adapter service running? Yes
Is the IIS site binding to net.tcp set to 808:*? Yes
Is Enabled Protocols under Advanced Settings for the site in IIS set to http,net.tcp? Yes
Is the server listening on port 808? Yes, checked with netstat -an |find /i "listening"
Is a port 808 open in the firewall? Yes.
Firewall is turned off on the server.
I can telnet to the server on port 808 from outside with telnet mydomain.com 808
In the configuration of the service on the server, the following was confirmed:
baseAddress is adjusted to net.tcp://mydomain.com:808/SignalR/ServerHubService.svc
This was localhost before, but changed to mydomain.com after it didn't work on the server: <identity><dns value="mydomain.com" /></identity>
It has been tested with a client locally on the server and on another server. Both can connect to port 808 with telnet and both give the same error message.
What configuration could be missing on the server? I am so close to the goal. Please assist me in troubleshooting this and complete the question.
Here is the client configuration on the server calling the service:
<system.serviceModel>
<bindings>
<netTcpBinding>
<binding name="MyServiceEndpoint" />
</netTcpBinding>
</bindings>
<client>
<endpoint address="net.tcp://mydomain.com:808/SignalR/ServerHubService.svc"
binding="netTcpBinding" bindingConfiguration="MyServiceEndpoint"
contract="ServerHubService.ServerHubService" name="MyServiceEndpoint">
<identity>
<dns value="mydomain.com" />
</identity>
</endpoint>
</client>
</system.serviceModel>
I also tried without 808 configured in the endpoint, as this is rumored to be the default port for net.tcp connections. However, it still gives the same result.
Instead of trying lots of things randomly, the good question is perhaps: How does one debug something like this? Can I install a program on either server that will tell me exactly WHY this call is being blocked?
With Wireshark configured like this, it's possible to look at the call coming to the server on port 808 and possibly determine why the call doesn't work. However, I have no idea how to analyze this at present time.
Good luck
I gave up and implemented this in the socket layer instead. It worked immediately. I hope this can help someone else, though. I'm setting an answer because many of the issues were solved and it did work locally eventually, so any problem remaining is probably related to me specific environment.
You have to generate the Proxy based on the metadata exposed over HTTP for tcp.(make sure httpGetEnabled is set to true). The address you use at the client should be the hosted address. Please refer the below post.
http://blogs.msdn.com/b/swiss_dpe_team/archive/2008/02/08/iis-7-support-for-non-http-protocols.aspx
In your question you mentioned that you connected to "test.mydomain.com" but the error changed the server to "computername". Then in your comment you mentioned it still failing to connect. If you wish to have the alias returned in the WSDL/MEX Add the useRequestHeadersForMetadataAddress node in your service behavior. Here is the MSDN information on this node: MSDN useRequestHeadersForMetadataAddress node
This is how your config should look. This takes into account answer given by Prasath (httpGetEnabled="true").
<serviceBehaviors>
<behavior name="ServerHubBehavior">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false" />
<useRequestHeadersForMetadataAddress>
<defaultPorts>
<add scheme="net.tcp" port="808" />
</defaultPorts>
</useRequestHeadersForMetadataAddress>
</behavior>
</serviceBehaviors>
Hosting a TCP Based service in IIS has always been a bear. WCF makes it very easy to run your own service host, listening on your TCP port. My recommendation would be to do that and set it up to run as a Windows Service.
See this article: http://msdn.microsoft.com/en-us/library/ff649818.aspx
I am guessing the issue you are having is that you need to setup the SPN (Service Principal Name) for your WCF service (on the machine) and have it added to the service account under which the service is running.
If you are running it under the default app pool user, then you need to have the SPN configured for the machine.
I know it is troubling, and typically is the surprise waiting fro us devs once our service is ready to deploy to production or pre-production environments.
The SPN is used by Kerberos during the authentication process.
Try using the IP of the machine to resolve your service instead of the hostname. (This is not supposed to require an SPN), replace "test.mydomain.com" by the machine IP address:
<host>
<baseAddresses>
<add baseAddress="net.tcp://192.168.0.253:808/SignalR/ServerHubService.svc" />
</baseAddresses>
</host>
Take a look at these articles:
- Kerberos for the Busy Admin
- WCF on intranet with windows authentication
- For the following post, try to read the one that is not accepted as an answer: What SPN do I need to set for a net.tcp service?
Did you tried to host service (for the testing purpose) in a Windows service on your local machine? This way you will at least know if the problem is on the service side or it's IIS/server configuration.
You have Net.TCP Port sharing service running on the server I guess... haven't found it explicitely stated.
I had a similar problem here today, while calling a net.tcp wcf service from inside an asp.net web api. I won't say that from all the other machines this service has worked for years, but the calls were made wcf self hosting, wcf iis asp.net compatibility hosting -> against the net.tcp service self hosted. When then I published my simple web api calling the same net.tcp service, everything went wrong, and all the connection were aborted without any reason, even the full wcf tracing both sides (service and client) did not helped, just telling the same "connection aborted".
I've already knew that net.tcp comes with the security over transport enabled, using windows authentication to sign and crypt the communication, so well, I just tried to turn off the security and everything start to work properly.
Just give it a try turning off the security in this way both sides (client and service):
<security mode="None"/>
full service binding:
<netTcpBinding>
<binding name="netTcpBinding" portSharingEnabled="true">
<security mode="None"/>
</binding>
</netTcpBinding>
I hope this can help you too.
WCF Service
WCF service hosting in Windows Services
WinService log on as Network Service
Host app config :
<service name="StudyingControllerService.ControllerService">
<host>
<baseAddresses>
<add baseAddress="http://IP:PORT/ControllerService.svc"/>
</baseAddresses>
</host>
<endpoint address=""
binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_IControllerService"
contract="StudyingControllerService.IControllerService" />
</service>
Everything work fine in local network. (localhost)
But I want to access my service from another computers via network.
I used another computer(from another localation), did ping IP (winservice's). ping was OK.
I installed my client and tried to connect to my remote service, but connect failed.
telnet also can't establish connection.
What is wrong?
Firewalls are disconnected. (on both sides)
On the client side telnet cant open connection to IP PORT
There is no problem with windows service or WCF. Problem was with my internet provider.
It blocked port which used my service. So, I ask to administrator to open port. and now everything is OK.
Thanks all for answers.
I had a similar issue. It was just abut opening the PORT on windows firewall.
Just to test if that would work, i turned off the firewall service.
Hope that helps!
I would try changing your base address in your config file, as follows:
<service name="StudyingControllerService.ControllerService">
<host>
<baseAddresses>
<add baseAddress="http://IP:PORT"/>
</baseAddresses>
</host>
<endpoint address="ControllerService.svc"
binding="basicHttpBinding"
bindingConfiguration="BasicHttpBinding_IControllerService"
contract="StudyingControllerService.IControllerService" />
</service>
My reason for recommending this is that the base address is used to allow endpoints to be added relative to the base address - putting the endpoint in the base address may be causing the issue.
Something to try at least - a couple minutes of editing and you'll have an answer one way or the other.
My employers website has multiple hostnames that all hit the same server and we just show different skins for branding purposes.
Unfortunately WCF doesn't seem to work well in this situation.
I've tried overriding the default host with a custom host factory.
That's not an acceptable solution because it needs to work from all hosts, not just 1.
I've also looked at this blog post but either I couldn't get it to work or it wasn't meant to solve my problem.
The error I'm getting is "This collection already contains an address with scheme http"
There's got to be a way to configure this, please help :)
If you don't put an address in the endpoint then it should resolve to whatever server hits the service. I use this code and it resolves both to my .local address and to my .com address from IIS.
<system.serviceModel>
<services>
<service name="ServiceName" behaviorConfiguration="ServiceName.Service1Behavior">
<endpoint address="" binding="wsHttpBinding" contract="iServiceName">
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="ServiceName.Service1Behavior">
<!-- 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="true"/>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
I don't think that the host base addresses solution posted above will work for IIS-hosted websites (the OP did mention that this was for his employer's website).
See this blog post
Also, the other answer further up by thaBadDawg won't work where multiple host headers are specified - you'll just get the errors that the OP mentions ("This collection already contains an address with scheme http".)
I don't think any of the solutions mentioned so far will work, because it doesn't look like WCF allows a single service to be accessible for a single site with multiple host headers from all of the sites. The only workaround I could find for .Net 3.5 (and under) is to create a different contract for each of the host headers, and use the custom ServiceHostFactory to use the correct host header based on which contract is specified. This isn't at all practical. Apparently .Net 4.0 will resolve this issue.
I met this problem several days ago. Actually I have the same situation that Ryu described originally in his question. We have one virtual directory for many customers but each of them has his own binding. Like "http://company1.product.com", "http://company2.product.com" etc.
Solution described here works. But what is the price! We should change web.config each time when we need to add new binding. And also web.config should contain absolute path prefix
like <add prefix=”http://company1.product.com”/>.
It is possible to bypass first problem. I wrote my own CustomHostFactory for WCF service, where I dynamically add endpoints. And this endpoints I retrieve from IIS bindings(there is a way to get information from IIS).
Here is sample code :
protected override ServiceHost CreateServiceHost(Type serviceType, Uri[] baseAddresses)
{
var serviceHost = base.CreateServiceHost(serviceType, baseAddresses);
var webHttpBinding = new WebHttpBinding();
var serviceEndpoint1 = serviceHost.AddServiceEndpoint(typeof(IService), webHttpBinding,
"http://company2.product.com/WCFService/Service.svc");
var serviceEndpoint2 = serviceHost.AddServiceEndpoint(typeof(IService), webHttpBinding,
"http://company1.product.com/WCFService/Service.svc");
var webHttpBehavior = new WebHttpBehavior();
serviceEndpoint1.Behaviors.Add(webHttpBehavior);
serviceEndpoint2.Behaviors.Add(webHttpBehavior);
return serviceHost;
}
And instead of hardcoding endpoint urls, you sould retrieve them from IIS.
But ServiceHost is created once when application starts. So if you need to add new binding, you should restart IIS. It is not a solution for us.
That is why we decided to move to asmx (like is described here).
And wait until Framework 4.0 release, where multiple bindings should be supported.
A simple workaround that doesn't involve any code or config changes is to create yet another website in IIS which points to the same physical directory, and the same app pool, but with a different host-header binding. This can be done for as many different host names as you have.
I'm sure you've figured it out by now, but just for fun I'll post here anyway.
I've had this exact problem and spent forever trying to figure it out. The best solution is to put the host base addresses in your service definition, which allows the service to operate under these multiple addresses. For this solution to work, you still need the ServiceHostFactory to be overridden. Since you've already done that, just leave it in there.
<service behaviorConfiguration="ServiceBehaviour" name="Api.Service">
<endpoint address="soap" binding="basicHttpBinding" contract="Api.IService" />
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
<host>
<baseAddresses>
<add baseAddress="http://host1.com/Api" />
<add baseAddress="http://host2.com/Api" />
</baseAddresses>
</host>
</service>