By Alejandro Villarreal
Hosting WCF services in IIS is usually a very straightforward process with no weird configuration settings or obscure errors. You create a site in IIS, publish your service in the site’s folder, and you’re ready to go.
However, things start to get a bit complicated in more advanced scenarios like the one I encountered some days ago: if your site in IIS answers to multiple host-headers, then when you try to access the service through a web browser, instead of seeing the usual page with the service description you will receive a screen indicating a Runtime Error, and you should be able to find an Error entry in Window’s Event Viewer (under “Windows Logs”/Application) whose Source is System.ServiceModel 3.0.0.0 (or whatever version you happen to be using), that says something like this:
Exception: System.ServiceModel.ServiceActivationException: The service '/YourService.svc' cannot be activated due to an exception during compilation. The exception message is: This collection already contains an address with scheme http. There can be at most one address per scheme in this collection.
This message was certainly more obscure than the errors I was used to when dealing with IIS-hosted WCF Services, and it didn’t make much sense until I found the solution and understood what the error was talking about. In summary, when the WCF Service is hosted in an IIS site, IIS passes all the host-headers to which the site answers as base addresses for the service when it instantiates it, and it in turn complains because it only expects 1 base address of a particular type. Several host-headers imply several base addresses for http, and thus the error.
A code-based solution is to create a custom class than inherits from ServiceHostFactory and filters out the unwanted addresses, and then tell IIS to use that class to instantiate your service. The class is nothing special:
Instead of returning the first address that was passed in (baseAddresses[0]) –which could impact your service if it depends heavily on this address, and the order of the host-headers changes in IIS– you can implement your own custom logic to determine which address the service is going to use.
Then you must tell IIS to actually use this class, which is achieved by modifying the .svc file that was generated when publishing your service, so it looks like this (notice the second line):
<%@ ServiceHost Service="Your.Namespace.YourService"
Factory="Your.Namespace.CustomHostFactory" %>
“CustomHostFactory” is just the name of the class you created, so it will depend on the actual name you give to it.
And that’s it! If you try to access your service through the web browser again, you should get the .NET generated help page. According to the site linked earlier, there is also a way to make this happen purely by editing the configuration file, but I haven’t tested it. However, feel free to go ahead and try it!
Have a nice day!
Get the best nearshore services for all your website and mobile app development needs. We’re sure to exceed your expectations and find a solution to exceed expectations.
ReplyDelete