I have an application written in ASP.NET MVC 4. I got access to remote web service. I added it to my solution as WebReference. When i call it's methods on my localhost all works great, the problem is on deployed version. Server provider run it as "Medium Trust". When i call WebService methods from hosted application i got an error:
I think the problem is in firewall rules on hosting server, my binding type for the service is "basicHttpBinding" with defaults settings. In this case my listening port is random, so how i can get through it? How to set static listening port for WebService response, so i can ask hosing provider to set firewall port open for my application?
My binding config:
<client>
<endpoint address="http://WebServiceURL:8585/Api" binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_IETRService" contract="ETRService.IETRService" name="BasicHttpBinding_IETRService" />
</client>
When you deploy, you should be listening on a standard port, I would assume (remove the port :8585) from your local testing in order to connect to your server.
<client>
<endpoint address="http://WebServiceURL/Api" binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_IETRService" contract="ETRService.IETRService" name="BasicHttpBinding_IETRService" />
</client>
Related
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.
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.
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.
I created a WCF service which is hosted in windows service. I created a proxy using svcutil
“svcutil.exe http://localhost:8000/ServiceModelSamples/FreeServiceWorld?wsdl”
It generated an output.config file and proxy class.
The output.config has the following element
<client>
<endpoint address="http://localhost:8000/ServiceModelSamples/FreeServiceWorld"
binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_IWeather"
contract="IWeather" name="WSHttpBinding_IWeather">
<identity>
<servicePrincipalName value="host/sdfsf.sdfs.com" />
</identity>
</endpoint>
</client>
I created a website (as client) and added a new C# file (MyFile.cs) into it. I copied the contents of the proxy class into MyFile.cs.
[The output.config is not copied to the web site]
In the code behnid of aspx, I am using the following code
WeatherClient client= new WeatherClient("WSHttpBinding_IWeather");
It throws an exception as “Could not find endpoint element with name 'WSHttpBinding_IWeather' and contract 'IWeather' in the ServiceModel client configuration section.”
Could you please help me to understand the missing link here?
You need to add the elements in output.config to the web.config of the web site for the client to know where to look for the service. If the client isn't running on the same machine as the service you will need to exchange localhost for the IP address or host name of the machine running the service.