Setting up WCF TCP service in a web application - c#

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.

Related

Hosting WCFService Library on IIS 10 with SSL encryption

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

WCF configuration for webHttpBinding with SSL terminated at load balancer

I have a WCF REST service using the webHttpBinding, and I am having some trouble getting it to work in a test environment behind an F5 load balancer - at least I believe the load balancer is an issue.
The service has been proven to run and operate locally using either http or https ("works on my machine"). The service is hosted in the same site that is consuming it.
Our test environment sits behind an F5 load balancer, which terminates SSL and forwards the request to server over http. Our IT staff has indicated that all incoming traffic to the test environment is http, and maintains that the site is configured with both http and https bindings in IIS. The only apparent difference between my local machine and the test environment is that my local machine is IIS 8 and the test environment is IIS 7.5.
The routes are registered like this:
RouteTable.Routes.Add(new ServiceRoute("REST/stuff", new WebServiceHostFactory(), typeof(StuffService)));
Currently, this is the relevant config that works locally:
<system.serviceModel>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true"/>
<standardEndpoints>
<webHttpEndpoint>
<standardEndpoint name="" helpEnabled="true" automaticFormatSelectionEnabled="true">
<security mode="Transport"/>
</standardEndpoint>
</webHttpEndpoint>
</standardEndpoints>
<bindings>
<webHttpBinding>
<binding>
<security mode="Transport"/>
</binding>
</webHttpBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<behavior name="">
<serviceMetadata httpGetEnabled="false" httpsGetEnabled="true" />
</behavior>
</serviceBehaviors>
</behaviors>
Initially, this service was deployed to the test environment without SSL, and I received this error when accessing a page that utilized the service:
Mixed Content: The page at 'https://foo.bar.com/thing.aspx' was loaded over HTTPS, but requested an insecure XMLHttpRequest endpoint 'http://foo.bar.com/REST/stuff/'. This request has been blocked; the content must be served over HTTPS.
That seems mysterious to me now, since the site was accessed over https, and the call to the service was using a relative URL. Unfortunately, I cannot debug this now since I changed the configuration.
At the time I received the error above, I did not know about the F5, and figured that all I needed to do was to configure my service to use transport security, as in the above configuration. After changing configuration to use transport security, the service fails to activate in the test environment, initiating this error on the server:
The service '/REST/stuff' cannot be activated due to an exception during compilation. The exception message is: Could not find a base address that matches scheme https for the endpoint with binding WebHttpBinding. Registered base address schemes are [http].
This, I believe, indicates that the service is expecting to operate using https, but the lack of https in registered base address schemes is preventing that, so the service cannot initialize at all. I understand that this may happen when the https binding is missing in IIS (though IT maintains it is not).
I am not sure what else I can do to enable my use case. Any help is greatly appreciated!
My config was fine. For some reason, when interacting through the load-balancer the client side was not using https when using relative URIs to call services. More information on what I believe to be my problem here: How to use HTTPS in AngularJS

What is running my WCF Service?

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.)

Hosting provider blocks webservice response - (1and1 hosting)

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>

Windows Service Hosted TCP WCF Service

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.

Categories

Resources