If you have started developing web services with Windows Communication Framework (WCF) you will no doubt have noticed that it is cleaner and more powerful than the old ASP.NET framework. However there are some hidden pitfalls. In particular WCF is a lot more finicky about how the web server is configured. If you aren’t careful this can cause code
that works in your test environment to mysteriously fail when moved to production. Here are some pointers on how to avoid these problems.
A lot of these problems have to do with the fact that production servers often host multiple web sites, distinguised by some combination of IP address, TCP port and HTTP host header. In IIS Manager these are specified in the “Web site identification” section of the “Web Site” tab. (Press the “Advanced” button to set host headers for the site.)
Since WCF is sensitive to these settings it is a very good idea to put any new WCF web services in a separate web site from any older ASP.NET services. Othewise if you have to tweak the site settings to get WCF to work you may cause problems for some of the older services.
One problem occurs if you use host headers to select the web site. In that case you must use only ONE host header for this. Otherwise WCF (as of .NET 3.0) will break. If you use exactly one host header then all clients must call the web service using the same absolute URL. No use of relative URLs, partial domain names, fixed IP addresses, etc. can be supported.
(This implies that you should install and test the new web services in production before freezing any client code. That is a good idea anyway.)
A related problem occurs if you have code that calls OperationContext.Current.Channel.LocalAddress.Uri (perhaps to determine the address of a related web service.) This will probably work fine in your test environment, but on a production server with multiple web sites with different IP addresses this will tend to break, returning a non-functional URI.
The solution, once again, is to configure your web site with exactly ONE host header, and require all callers to use it.