WCF services behind NAT problem and solution
Problem: We have a set of WCF services working on a server. We have an ordinary ASP.NET page that calls one of the services to display its state. When we call that page we is supposed to look like this:
Green page indicates everything works fine.
At a customers we’ve installed the services.
The message was: There was no endpoint listening at http://…/Services/BasicDataService.svc/DeliverServiceState that could accept the message. This is often caused by an incorrect address or SOAP action. See InnerException, if present, for more details.
We quickly discovered that there was nothing wrong with the services. Our app worked fine and we were able to call the “.svc” endpoint in the browser.
But why do we get this exception?
A quick call to the service on the server reviled no response (“This page can’t be displayed”). Ping to the domain reviled “Request timed out.”. Oh, we are getting nearer. Our status page calls the services from the inside of the customers network (both website and services are in the same site on IIS). It looks like we are in NAT. The requests coming to the company router from outside are correctly routed to the server working inside the the company network. The domain name is translated with help of DNS to the global IP address and the company router routes the communication to the server which works with his local IP address. But if we are connecting from inside we are hitting wrong side of the router and it is not able to translate the global IP to the local IP correctly. We are not landing where we supposed to.
Reconfiguration on the company router should do the trick (NAT-Loopback). We informed the company admin to do the change and proceed with a quick workaround. We changed the hosts file to fix it right away.
Hosts is a text file located in C:\Windows\System32\drivers\etc used by the system to locally route the addresses to IPs. We can add the server local IP address and match it with the domain name.
That solved the problem. But soon we got another one.
We added a second binding to the site and our information page wen red once again. This one was actually easy to solve. We called the ”.svc” service directly and got:
This collection already contains an address with scheme http. There can be at most one address per scheme in this collection. If your service is being hosted in IIS you can fix the problem by setting ‘system.serviceModel/serviceHostingEnvironment/multipleSiteBindingsEnabled’ to true or specifying ‘system.serviceModel/serviceHostingEnvironment/baseAddressPrefixFilters’.
Parameter name: item
Yep, multiple bindings present but WCF configured to work with only one. We had to change the:
<serviceHostingEnvironment multipleSiteBindingsEnabled="false" />
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
in the services web.config.
We added the second address to the hosts file and voila!